Brunoy
(乐神)
1
使用 useState函数 的set设置新值后,基于通常逻辑总想立即利用该新值做其他操作,结果这个值不是最新值。简单的示例代码如下:
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
console.log("Count:", count) // 即使页面显示的count是最新值,此处输出的count仍然是旧值
};
使用 handleClick() 函数时,每次控制台输出的count都是旧值,而不是setCount(count + 1)设置的新值。经搜索知道setCount()这种useState设置值的函数是异步函数,所以在console.log()执行时,count值还没更新。
如何让console.log()立即显示新值,后来找到了解决办法用 useRef函数,具体代码如下:
const [count, setCount] = useState(0);
const countRef = useRef(0);
const handleClick = () => {
countRef.current++;
setCount(countRef.current);
console.log("Count:", countRef.current) // 此处输出的count是最新值
};
还有一种方法是用 useEffect函数解决,但是用 useEffect 时,console.log() 函数就要写到useEffect里面,相关逻辑代码被拆分分散在不同位置,感觉不是很适应。
还有什么更好的方法吗?
1 Like
handleClick
用useCallback
来定义不好么,依赖count
即可
const handleClick = useCallback(() => {
setCount(count + 1);
console.log("Count: ", count);
}, [count]);
1 Like
log
4
这样不行吗, setCount 为什么一定要先执行呢
const [count, setCount] = useState(0);
const handleClick = () => {
const newCount = count + 1;
console.log("Count:", newCount ) // 即使页面显示的count是最新值,此处输出的count仍然是旧值
setCount(newCount );
};
Brunoy
(乐神)
6
这样有时候不太方便,无法在其他函数读取到newCount这个值
sunnysun
(Chirou)
7
拖后腿了,除了第三方库,现在只能想到自己封装一个带 Callback 的 useState 或者去 useEffect 里获取到最新值 
你这种写法,count的值在组件渲染的时候就固定下来了,不会随着实际的count
变化而变化。而使用useCallback
可以让count
发生变化的时候刷新handleClick
的定义,于是函数体里的count
也就更新了。
这个主要涉及到Javascript里闭包的知识,你可以去参考一下。
leroy
(leroy)
9
setCount(count => count + 1) 可以试试这种,不过没啥意义。
useState 本身设计理念就是闭包,新数据只在下一次render时生效,当前获取的不会因修改而改变。
用useEffect比较合适,可以理解为click事件只做状态的赋予,而useEffect里面处理状态值改变而引发的副作用逻辑。
wang
(王小帅°)
11
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
};
useEffect(() => {
console.log(“Count:”, count) // 页面显示的count是最新值
}, [count]);