基本案例
function App() {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(2);
func(); // 点击后打印 0
};
const func = () => {
console.log(count);
};
return (
<div className="App">
<button onClick={handleClick}>点击</button>
</div>
);
}
复制代码
当我们点击按钮时,控制台打印的还是上一次的值0,而不是最新的2
因为在react合成事件中改变状态是异步的,出于减少render次数,react会收集所有状态变更,然后比对优化,最后做一次变更,在代码中可以看出,func的调用和setCount在同一个宏任务中,这是react还没有render,所以直接使用count获取的肯定是上一次闭包里的值0
有的人可能会说,直接将最新的值当作参数传递给func不就行了吗,对,这也是一种解决办法,但是有时不只是一个状态,可能要传递的参数很多,再有也是出于对react-hooks的深入研究,所以我选择通过自定义hooks实现在useState改变值之后立刻获取到最新的值,我们先看下实现的效果,代码变更如下:
function App() {
const [count, setCount] = useState(0);
const handleClick = () => {
setstate(2);
func(); // 打印 2
};
/** 将func的方法传递给useSyncCallback然后返回一个新的函数 */
const func = useSyncCallback(() => {
console.log(count);
});
return (
<div className="App">
<button onClick={handleClick}>点击</button>
</div>
);
}
export default App;
复制代码
如何实现useSyncCallback?
import { useEffect, useState, useCallback } from 'react';
const useSyncCallback = callback => {
const [proxyState, setProxyState] = useState({ current: false });
const Func = useCallback(() => {
setProxyState({ current: true });
}, [proxyState])
useEffect(() => {
if (proxyState.current === true) setProxyState({ current: false });
}, [proxyState])
useEffect(() => {
proxyState.current && callback();
})
return Func
}
export default useSyncCallback;
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END