useTimeout
是可以在函数式组件中,处理 setTimeout
计时器函数
解决了什么问题?
如果直接在函数式组件中使用 setTimeout
,会遇到以下问题:
- 多次调用setTimeout
function App() {
const [state, setState] = useState(1);
setTimeout(() => {
setState(state + 1);
}, 3000);
return (
// 我们原本的目的是在页面渲染完3s后修改一下state,但是你会发现当state+1后,触发了页面的重新渲染,就会重新有一个3s的定时器出现来给state+1,既而变成了每3秒+1。
<div> {state} </div>
);
}
- hooks 的闭包缺陷
function App() {
const [count, setCount] = useState(0);
const [countTimeout, setCountTimeout] = useState(0);
useEffect(() => {
setTimeout(() => {
setCountTimeout(count);
}, 3000);
setCount(5);
}, []);
return (
//count发生了变化,但是3s后setTimout的count却还是0
<div>
Count: {count}
<br />
setTimeout Count: {countTimeout}
</div>
);
}
useTimeout 实现
function useTimeout(callback, delay) {
const memorizeCallback = useRef();
useEffect(() => {
memorizeCallback.current = callback;
}, [callback]);
useEffect(() => {
if (delay !== null) {
const timer = setTimeout(() => {
memorizeCallback.current();
}, delay);
return () => {
clearTimeout(timer);
};
}
}, [delay]);
}
如何使用
// callback 回调函数, delay 延迟时间
useTimeout(callback, delay);