15 个自定义 Hooks 让你的 React 组件更轻量
这里有 15 个自定义钩子,可以让你的 React 组件变得轻量级
React Hooks 是 React 社区的热门词汇。我希望每个 React 开发者都知道什么是 Hooks。简单来说,Hooks 让函数式组件的生命周期方法更加便捷,也鼓励我们编写函数式组件。
让我们深入研究自定义钩子!自定义钩子可以将组件逻辑提取到可复用的函数中,从而提高组件拆分和可靠性。这里我们将介绍 15 个React-use包中的自定义钩子,它们可以使我们的组件更轻量。
1. useIdle
useIdle 钩子用于跟踪页面上的用户是否处于空闲状态。您可以传递两个参数——一个是考虑空闲的时间,另一个是 initialState,用于设置用户初始状态。
import {useIdle} from 'react-use';
const Demo = () => {
const isIdle = useIdle(3e3);
return (
<div>
<div>User is idle: {isIdle ? 'Yes 😴' : 'Nope'}</div>
</div>
);
};
2. useInterval
此钩子用于与间隔相关的功能。它会clearInterval
自动处理组件的卸载。它还允许通过将延迟设置为空来暂停间隔。
import * as React from 'react';
import {useInterval} from 'react-use';
const Demo = () => {
const [count, setCount] = React.useState(0);
const [delay, setDelay] = React.useState(1000);
const [isRunning, toggleIsRunning] = useBoolean(true);
useInterval(
() => {
setCount(count + 1);
},
isRunning ? delay : null
);
return (
<div>
<div>
delay: <input value={delay} onChange={event => setDelay(Number(event.target.value))} />
</div>
<h1>count: {count}</h1>
<div>
<button onClick={toggleIsRunning}>{isRunning ? 'stop' : 'start'}</button>
</div>
</div>
);
};
3. 使用Scroll
此钩子用于监听元素的滚动事件,并在滚动时重新渲染。无需手动添加 JavaScript 事件监听器。
import {useScroll} from 'react-use';
const Demo = () => {
const scrollRef = React.useRef(null);
const {x, y} = useScroll(scrollRef);
return (
<div ref={scrollRef}>
<div>x: {x}</div>
<div>y: {y}</div>
</div>
);
};
4. useToggle
此钩子用于在两个状态(例如 TRUE 和 FALSE)之间切换。这种方法减少了手动逻辑。
import {useToggle} from 'react-use';
const Demo = () => {
const [on, toggle] = useToggle(true);
return (
<div>
<div>{on ? 'ON' : 'OFF'}</div>
<button onClick={toggle}>Toggle</button>
<button onClick={() => toggle(true)}>set ON</button>
<button onClick={() => toggle(false)}>set OFF</button>
</div>
);
};
5. 使用标题
此钩子用于设置页面标题。
import {useTitle} from 'react-use';
const Demo = () => {
useTitle('Hello world!');
return null;
};
6. usePrevious
此钩子用于获取先前的状态。我们可能不需要编写自定义逻辑来获取先前的状态。
import {usePrevious} from 'react-use';
const Demo = () => {
const [count, setCount] = React.useState(0);
const prevCount = usePrevious(count);
return (
<p>
<button onClick={() => setCount(count + 1)}>+</button>
<button onClick={() => setCount(count - 1)}>-</button>
<p>
Now: {count}, before: {prevCount}
</p>
</p>
);
};
7. useSetState
此钩子用于将对象合并到其当前状态,类似于this.setState
类组件中的 。如果您使用多个状态,可以使用useSetState
import {useSetState} from 'react-use';
const Demo = () => {
const [state, setState] = useSetState({});
return (
<div>
<pre>{JSON.stringify(state, null, 2)}</pre>
<button onClick={() => setState({hello: 'world'})}>hello</button>
<button onClick={() => setState({foo: 'bar'})}>foo</button>
<button
onClick={() => {
setState((prevState) => ({
count: (prevState.count || 0) + 1,
}))
}}
>
count
</button>
</div>
);
};
8. 使用Cookie
此钩子用于返回 cookie 的当前值、更新 cookie 的回调和删除 cookie 的回调。
import { useCookie } from "react-use";
const Demo = () => {
const [value, updateCookie, deleteCookie] = useCookie("my-cookie");
const [counter, setCounter] = useState(1);
useEffect(() => {
deleteCookie();
}, []);
const updateCookieHandler = () => {
updateCookie(`my-awesome-cookie-${counter}`);
setCounter(c => c + 1);
};
return (
<div>
<p>Value: {value}</p>
<button onClick={updateCookieHandler}>Update Cookie</button>
<br />
<button onClick={deleteCookie}>Delete Cookie</button>
</div>
);
};
9. 使用权限
此钩子用于获取浏览器 API 的权限状态。传递 API 名称即可获取权限状态。
import {usePermission} from 'react-use';
const Demo = () => {
const state = usePermission({ name: 'microphone' });
return (
<pre>
{JSON.stringify(state, null, 2)}
</pre>
);
};
10. 使用Debounce
此钩子用于延迟事件,直到等待时间结束。在下面的代码中,setState 是在等待时间结束后执行的。
const Demo = () => {
const [state, setState] = React.useState('Typing stopped');
const [val, setVal] = React.useState('');
const [debouncedValue, setDebouncedValue] = React.useState('');
const [, cancel] = useDebounce(
() => {
setState('Typing stopped');
setDebouncedValue(val);
},
2000,
[val]
);
return (
<div>
<input
type="text"
value={val}
placeholder="Debounced input"
onChange={({ currentTarget }) => {
setState('Waiting for typing to stop...');
setVal(currentTarget.value);
}}
/>
<div>{state}</div>
<div>
Debounced value: {debouncedValue}
<button onClick={cancel}>Cancel debounce</button>
</div>
</div>
);
};
11. 使用地理定位
此钩子用于获取用户地理位置。useGeolocation 返回纬度、经度、海拔和更多信息。
import {useGeolocation} from 'react-use';
const Demo = () => {
const state = useGeolocation();
return (
<pre>
{JSON.stringify(state, null, 2)}
</pre>
);
};
12. useNetworkState
此钩子用于获取浏览器的网络状态。useNetworkState 可用于向用户显示连接状态。
import {useNetworkState} from 'react-use';
const Demo = () => {
const state = useNetworkState();
return (
<pre>
{JSON.stringify(state, null, 2)}
</pre>
);
};
13. 使用CopyToClipboard
useCopyToClipboard 钩子用于将文本复制到剪贴板。
const Demo = () => {
const [text, setText] = React.useState('');
const [state, copyToClipboard] = useCopyToClipboard();
return (
<div>
<input value={text} onChange={e => setText(e.target.value)} />
<button type="button" onClick={() => copyToClipboard(text)}>copy text</button>
{state.error
? <p>Unable to copy value: {state.error.message}</p>
: state.value && <p>Copied {state.value}</p>}
</div>
)
}
14. 使用Favicon
useFavicon 钩子用于设置页面的图标。
import {useFavicon} from 'react-use';
const Demo = () => {
useFavicon('https://cdn.sstatic.net/Sites/stackoverflow/img/favicon.ico');
return null;
};
15. 使用错误
useError 钩子用于调度错误。
import { useError } from 'react-use';
const Demo = () => {
const dispatchError = useError();
const clickHandler = () => {
dispatchError(new Error('Some error!'));
};
return <button onClick={clickHandler}>Click me to throw</button>;
};
// In parent app
const App = () => (
<ErrorBoundary>
<Demo />
</ErrorBoundary>
);
结论
react-use包中还有一些自定义钩子,希望对你有所帮助。感谢阅读。
想要了解更多?欢迎关注Twitter。
你可以给我买杯咖啡来支持我 ☕