【发布时间】:2019-08-13 11:19:17
【问题描述】:
在调用setInterval 函数之前,我已将状态设置为true。但即使 useEffect 钩子被状态的新值触发,它也不会反映在 setInterval 函数中。
这里的代码沙箱:https://jsfiddle.net/6e05tc2L/3/
let interval;
const Component = () => {
React.useEffect(() => {
console.log('State updated to', state);
});
const [state, setState] = React.useState(false);
const on = () => {
setState(true);
interval = setInterval(() => {
console.log(state);
}, 1000);
}
const off = () => {
setState(false);
clearInterval(interval);
}
const toggle = () => state ? off() : on()
return (<div>
<button onClick={toggle}>Toggle State</button>
</div>);
}
ReactDOM.render(
<Component />,
document.getElementById('container')
);
它不应该在更新后使用更新的 state 值吗?
【问题讨论】:
-
传递给
setInterval的函数在on被调用时只创建了1 次,它在创建时关闭了state的值。未来的渲染再次调用React.useState并“看到”一个新的state,但是在调用on时创建的函数基本上停留在过去:它在创建时关闭了state,并且永远不会得到新的state的值。 -
因此,如果您查看 Abramov 的
useInterval,它会在每次渲染时调用useEffect,并使用新版本的回调更新引用的.current,该回调的值超过state的值那个渲染调用。传递给本机setInterval的函数永远不会改变,但该函数所做的只是调用 另一个 函数,该函数的引用实际上正在在每次渲染时更新。 -
@RossAllen 因此回调函数由于使用了 useRef 而发生了变化,但 tick 函数保持不变。这很棒,但感觉很复杂。谢谢! :)
-
是的,没错。
tick永远不会改变,但是在您自己调用useInterval时,您会在每次渲染时传入一个新函数。该函数被设置为savedCallback.current并由永久tick调用。
标签: javascript reactjs setinterval react-hooks