ace*_*ndr 4 javascript setinterval reactjs react-hooks
在调用该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')
);
Run Code Online (Sandbox Code Playgroud)
一旦更新,它不应该使用更新的 state 值吗?
Muk*_*oni 12
您传递给 useEffect 的函数内的值在每次渲染时都会刷新,因为 useEffect 使用您传递给它的函数的新定义。
但是传递给 setInterval 的函数只定义了一次,它会关闭 state 的旧值。哪个还没有更新。
使用钩子关闭闭包很棘手,但要意识到 useEffect 为每个渲染创建一个新函数,因此每次函数关闭一个新的状态值时。
诀窍是在 useEffect 本身内部调用与 setInterval 相关的代码,这本身取决于 state 的变化值
React.useEffect(() => {
if(state) {
interval = setInterval(() => {
console.log(state);
}, 1000);
} else {
clearInterval(interval);
}
}, [state]);
Run Code Online (Sandbox Code Playgroud)
或者,更好的是,使用 useInterval 钩子为您处理这些细节。
setInterval始终可以访问组件第一次渲染的值,因为传递给的函数setInterval会围绕该值关闭并且永远不会重新声明。您可以使用自定义挂钩来解决此问题:
function useInterval(callback, delay) {
const savedCallback = useRef();
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
useEffect(() => {
function tick() {
savedCallback.current();
}
let id = setInterval(tick, delay);
return () => clearInterval(id);
}, [delay]);
}
Run Code Online (Sandbox Code Playgroud)
该实现以及对 React Hooks 之间不匹配的全面解释setInterval来自React 贡献者之一 Dan Abramov 的Making setInterval Declarative with React Hooks 。
| 归档时间: |
|
| 查看次数: |
5309 次 |
| 最近记录: |