Skip to content

Commit 5881fa6

Browse files
committed
feat: 🎸 add useNetwork hook
1 parent c533b97 commit 5881fa6

File tree

6 files changed

+141
-3
lines changed

6 files changed

+141
-3
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ This is port of [`libreact`](https://github.com/streamich/libreact) to React Hoo
1818
- [`useLocation`](./docs/useLocation.md)
1919
- [`useMedia`](./docs/useMedia.md)
2020
- [`useMediaDevices`](./docs/useMediaDevices.md)
21+
- [`useNetwork`](./docs/useNetwork.md)
2122
- [`useOrientation`](./docs/useOrientation.md)
2223
- [`useSize`](./docs/useSize.md)
2324
- [`useWindowSize`](./docs/useWindowSize.md)

docs/useNetwork.md

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# `useNetwork`
2+
3+
React sensor hook that tracks connected hardware devices. Returns:
4+
5+
```json
6+
{
7+
"online": true,
8+
"since": "2018-10-27T08:59:05.562Z",
9+
"downlink": 10,
10+
"effectiveType": "4g",
11+
"rtt": 50
12+
}
13+
```
14+
15+
## Usage
16+
17+
```jsx
18+
import {useNetwork} from 'react-use';
19+
20+
const Demo = () => {
21+
const state = useNetwork();
22+
23+
return (
24+
<pre>
25+
{JSON.stringify(state, null, 2)}
26+
</pre>
27+
);
28+
};
29+
```

src/__stories__/useNetwork.story.tsx

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import * as React from 'react';
2+
import {storiesOf} from '@storybook/react';
3+
import {useNetwork} from '..';
4+
5+
const Demo = () => {
6+
const state = useNetwork();
7+
8+
return (
9+
<pre>
10+
{JSON.stringify(state, null, 2)}
11+
</pre>
12+
);
13+
};
14+
15+
storiesOf('useNetwork', module)
16+
.add('Example', () =>
17+
<Demo/>
18+
)

src/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import useLocation from './useLocation';
77
import useMap from './useMap';
88
import useMedia from './useMedia';
99
import useMediaDevices from './useMediaDevices';
10+
import useNetwork from './useNetwork';
1011
import useOrientation from './useOrientation';
1112
import useSize from './useSize';
1213
import useTitle from './useTitle';
@@ -23,6 +24,7 @@ export {
2324
useMap,
2425
useMedia,
2526
useMediaDevices,
27+
useNetwork,
2628
useOrientation,
2729
useSize,
2830
useTitle,

src/useNetwork.ts

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import {useState, useEffect} from './react';
2+
import {on, off} from './util';
3+
4+
export interface NetworkState {
5+
online?: boolean;
6+
since?: Date;
7+
downlink?: number;
8+
downlinkMax?: number;
9+
effectiveType?: string;
10+
rtt?: number;
11+
type?: string;
12+
}
13+
14+
const getConnection = () => {
15+
if (typeof navigator !== 'object') {
16+
return null;
17+
}
18+
const nav = navigator as any;
19+
return nav.connection || nav.mozConnection || nav.webkitConnection;
20+
};
21+
22+
const getConnectionState = (): NetworkState => {
23+
const connection = getConnection();
24+
if (!connection) {
25+
return {};
26+
}
27+
const {downlink, downlinkMax, effectiveType, type, rtt} = connection;
28+
return {
29+
downlink,
30+
downlinkMax,
31+
effectiveType,
32+
type,
33+
rtt
34+
};
35+
}
36+
37+
const useNetwork = (initialState: NetworkState = {}) => {
38+
const [state, setState] = useState(initialState);
39+
40+
useEffect(() => {
41+
let localState = state;
42+
const localSetState = (patch) => {
43+
localState = {...localState, ...patch};
44+
setState(localState);
45+
};
46+
const connection = getConnection();
47+
48+
const onOnline = () => {
49+
localSetState({
50+
online: true,
51+
since: new Date()
52+
});
53+
};
54+
const onOffline = () => {
55+
localSetState({
56+
online: false,
57+
since: new Date()
58+
});
59+
};
60+
const onConnectionChange = () => {
61+
localSetState(getConnectionState());
62+
};
63+
64+
on(window, 'online', onOnline);
65+
on(window, 'offline', onOffline);
66+
if (connection) {
67+
on(connection, 'change', onConnectionChange);
68+
localSetState({
69+
...state,
70+
online: navigator.onLine,
71+
since: undefined,
72+
...getConnectionState(),
73+
});
74+
}
75+
76+
return () => {
77+
off(window, 'online', onOnline);
78+
off(window, 'offline', onOffline);
79+
if (connection) {
80+
off(connection, 'change', onConnectionChange);
81+
}
82+
};
83+
}, [0]);
84+
85+
return state;
86+
};
87+
88+
export default useNetwork;

src/useOrientation.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
import {useState, useEffect} from './react';
22
import {on, off} from './util';
33

4-
export interface State {
4+
export interface OrientationState {
55
angle: number;
66
type: string;
77
}
88

9-
const defaultState: State = {
9+
const defaultState: OrientationState = {
1010
angle: 0,
1111
type: 'landscape-primary'
1212
};
1313

14-
const useOrientation = (initialState: State = defaultState) => {
14+
const useOrientation = (initialState: OrientationState = defaultState) => {
1515
const [state, setState] = useState(initialState);
1616

1717
useEffect(() => {

0 commit comments

Comments
 (0)