携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第21天,点击查看活动详情
💻文档地址:ahooks.js.org/zh-CN/
👨💻github地址:github.com/alibaba/hoo…
useNetwork
🧪 这是一个实验中的功能,在不同浏览器中适合使用的前缀。
function getConnection() {
const nav = navigator as any;
if (!isObject(nav)) return null;
return nav.connection || nav.mozConnection || nav.webkitConnection;
}
NetworkInformation 提供有关设备正在使用的连接与网络进行通信的信息。
| 属性 | 描述 | 类型 |
|---|---|---|
| online | 网络是否为在线 | boolean |
| since | online 最后改变时间 | Date |
| rtt | 当前连接下评估的往返时延 | number |
| type | 设备使用与所述网络进行通信的连接的类型 | bluetooth | cellular | ethernet | none | wifi | wimax | other | unknown |
| downlink | 有效带宽估算(单位:兆比特/秒) | number |
| downlinkMax | 最大下行速度(单位:兆比特/秒) | number |
| saveData | 用户代理是否设置了减少数据使用的选项 | boolean |
| effectiveType | 网络连接的类型 | slow-2g | 2g | 3g | 4g |
更多信息参考:MDN NetworkInformation
function getConnectionProperty(): NetworkState {
const c = getConnection();
if (!c) return {};
return {
rtt: c.rtt,
type: c.type,
saveData: c.saveData,
downlink: c.downlink,
downlinkMax: c.downlinkMax,
effectiveType: c.effectiveType,
};
}
在 useEffect 中,分别监听 online, offline, change 三个事件。
function useNetwork(): NetworkState {
const [state, setState] = useState(() => {
return {
since: undefined,
online: navigator?.onLine,
...getConnectionProperty(),
};
});
useEffect(() => {
const onOnline = () => {
setState((prevState) => ({
...prevState,
online: true,
since: new Date(),
}));
};
const onOffline = () => {
setState((prevState) => ({
...prevState,
online: false,
since: new Date(),
}));
};
const onConnectionChange = () => {
setState((prevState) => ({
...prevState,
...getConnectionProperty(),
}));
};
window.addEventListener(NetworkEventType.ONLINE, onOnline);
window.addEventListener(NetworkEventType.OFFLINE, onOffline);
const connection = getConnection();
connection?.addEventListener(NetworkEventType.CHANGE, onConnectionChange);
return () => {
window.removeEventListener(NetworkEventType.ONLINE, onOnline);
window.removeEventListener(NetworkEventType.OFFLINE, onOffline);
connection?.removeEventListener(NetworkEventType.CHANGE, onConnectionChange);
};
}, []);
return state;
}
useToggle
默认为 boolean 切换
默认为 false。setLeft 设置默认值,setRight,是否传入第二个参数,如果传入第二个参数,那么就设置为第二个参数,否则设置默认参数的反值。
function useToggle<D, R>(defaultValue = false, reverseValue) {
const [state, setState] = useState(defaultValue);
const actions = useMemo(() => {
const reverseValueOrigin = (reverseValue === undefined ? !defaultValue : reverseValue);
const set = (value) => setState(value);
const setLeft = () => setState(defaultValue);
const setRight = () => setState(reverseValueOrigin);
return {
set,
setLeft,
setRight,
};
}, []);
return [state, actions];
}
toggle 对两个值之间的切换。
const toggle = () => setState((s) => (s === defaultValue ? reverseValueOrigin : defaultValue));
Example
export default () => {
const [state, { toggle, set, setLeft, setRight }] = useToggle('Hello', 'World');
return (
<div>
<p>Effects:{state}</p>
<p>
<button type="button" onClick={toggle}>
Toggle
</button>
<button type="button" onClick={() => set('Hello')} style={{ margin: '0 8px' }}>
Set Hello
</button>
<button type="button" onClick={() => set('World')}>
Set World
</button>
<button type="button" onClick={setLeft} style={{ margin: '0 8px' }}>
Set Left
</button>
<button type="button" onClick={setRight}>
Set Right
</button>
</p>
</div>
);
};