[英]How to get updated state value in React useEffect hook
I'm listening to a scroll event in a function for a pagination feature.我正在收听 function 中的滚动事件以获取分页功能。 The scroll event is called inside a
useEffect
hook.在
useEffect
挂钩中调用滚动事件。 When the scroll event is fired, I want to make a HTTP call with a value already set in state, and update that value if the HTTP request is successful.触发滚动事件时,我想使用 state 中已设置的值进行 HTTP 调用,如果 HTTP 请求成功,则更新该值。
However, whenever the event fires, it only uses the initial value of the item in state, even though the value has been updated, and I can see the updated value outside of the function.但是,每当事件触发时,它只使用 state 中项目的初始值,即使该值已更新,并且我可以在 function 之外看到更新后的值。
How do I get the updated value inside the onScroll callback?如何在 onScroll 回调中获取更新的值?
Below is a code snippet下面是一个代码片段
const [test, setTest] = useState(0);
// The below commented out code works because it's not inside useEffect
// window.addEventListener('scroll', () => requestAnimationFrame(() => {
// console.log(test);
// setTest(test + 1);
// }));
useEffect(() => {
window.addEventListener('scroll', () => requestAnimationFrame(() => {
console.log(test); // this always returns 0
setTest(test + 1);
}));
}, [])
console.log(test); // this returns the updated/correct value.
By providing an empty array as the second argument to the effect, you've told react to never recreate this effect.通过提供一个空数组作为效果的第二个参数,您已经告诉 react 永远不要重新创建此效果。 So it happens just once, and the variables it has in its closure are never going to change.
所以它只发生一次,它在闭包中的变量永远不会改变。
Option 1:选项1:
You can get the effect to rerun by either removing the dependency array, or populating it with the variables you care about.您可以通过删除依赖数组或使用您关心的变量填充它来获得重新运行的效果。 Since this will result in the effect running multiple times you will also need to provide a cleanup function for tearing down the previous effect.
由于这将导致效果多次运行,您还需要提供清理 function 以拆除先前的效果。
useEffect(() => {
const callback = () => requestAnimationFrame(() => {
setTest(test + 1);
})
window.addEventListener('scroll', callback);
return () => window.removeEventListener('scroll', callback);
}) // <------
Option 2:选项 2:
Since the only thing you need to be refreshed is the latest value of state, you can use the callback version of setTest.由于唯一需要刷新的是state的最新值,所以可以使用setTest的回调版本。 React will pass you in the latest value, and you can compute the change based on that.
React 会将最新的值传递给你,你可以根据它计算变化。
You will still want to have a teardown function so that the listener can be removed if this component unmounts:您仍然需要拆解 function 以便在卸载此组件时可以删除侦听器:
useEffect(() => {
const callback = () => requestAnimationFrame(() => {
setTest(prev => prev + 1); // <------
})
window.addEventListener('scroll', callback);
return () => window.removeEventListener('scroll', callback);
}, [])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.