We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在hooks 中使用 setTimeout 方法,方法中访问到的函数 state 始终是初始值,而不是更新后的最新 state
在这个例子中,首先执行setCount 将 count 设为 5, 然后经过 3 秒后执行 setCountInTimeout, 将 countInTimeout 的值设置为count 的值
我们最初期望的是 这时候 countInTimeout 就等于 此刻 count 最新的值 5, 然而 countInTimeout 却保持了最开始的 count 值 0
import React, { useEffect, useState } from 'react'; const TimeoutExample = () => { const [count, setCount] = useState(0); const [countInTimeout, setCountInTimeout] = useState(0); useEffect(() => { setTimeout(() => { setCountInTimeout(count); // count is 0 here }, 3000); setCount(5); // Update count to be 5 after timeout is scheduled }, []); return ( <div> Count: {count} <br /> setTimeout Count: {countInTimeout} </div> ); }; export default TimeoutExample;
setTimeout 是一个闭包,setTimeout 函数执行的时候使用的参数 count 读取自setTimeout 函数创建的时候,即 0。 setTimeout 使用闭包的方式异步访问 count 的值。当整个函数组件re-render的时候,会创建出一个新的 setTimeout 函数一个新的闭包,但并没有改变最初封装它的那个闭包的值
作者也提到这么设计的初衷是满足这样的场景:比如订阅了一个ID,当随后需要取消订阅的时候,避免ID发生变化而造成不能取消订阅的问题
使用一个 container 来把最新的 state 也就是 count 的值穿进去,并在随后的 timeout 函数中读取最新的 state 。
可以使用 useRef。 通过 ref's current 来同步最新的 state, 然后在 timeout 函数中读取 current 的值。使用 ref 在异步callback函数中访问最新的 当前的 state
const countRef = useRef(count); countRef.current = count; const getCountTimeout = () => { setTimeout(() => { setTimeoutCount(countRef.current); }, 2000); };
参考: State from useState hook inside a setTimeout is not updated
The text was updated successfully, but these errors were encountered:
useCallback deps 加上 count?
Sorry, something went wrong.
No branches or pull requests
问题
在hooks 中使用 setTimeout 方法,方法中访问到的函数 state 始终是初始值,而不是更新后的最新 state
demo
在这个例子中,首先执行setCount 将 count 设为 5, 然后经过 3 秒后执行 setCountInTimeout, 将 countInTimeout 的值设置为count 的值
我们最初期望的是 这时候 countInTimeout 就等于 此刻 count 最新的值 5, 然而 countInTimeout 却保持了最开始的 count 值 0
原因
setTimeout 是一个闭包,setTimeout 函数执行的时候使用的参数 count 读取自setTimeout 函数创建的时候,即 0。 setTimeout 使用闭包的方式异步访问 count 的值。当整个函数组件re-render的时候,会创建出一个新的 setTimeout 函数一个新的闭包,但并没有改变最初封装它的那个闭包的值
作者也提到这么设计的初衷是满足这样的场景:比如订阅了一个ID,当随后需要取消订阅的时候,避免ID发生变化而造成不能取消订阅的问题
解决方法
使用一个 container 来把最新的 state 也就是 count 的值穿进去,并在随后的 timeout 函数中读取最新的 state 。
可以使用 useRef。 通过 ref's current 来同步最新的 state, 然后在 timeout 函数中读取 current 的值。使用 ref 在异步callback函数中访问最新的 当前的 state
参考:
State from useState hook inside a setTimeout is not updated
The text was updated successfully, but these errors were encountered: