如何在React useEffect挂钩中获取更新的状态值

时间:2020-04-12 13:16:22

标签: javascript reactjs react-hooks

我正在监听分页功能中的滚动事件。滚动事件在useEffect挂钩内调用。触发滚动事件后,我想使用状态已设置的值进行HTTP调用,如果HTTP请求成功,则更新该值。

但是,每当事件触发时,即使该值已更新,它也仅使用处于状态的项目的初始值,而且我可以在函数外部看到更新后的值。

如何在onScroll回调中获取更新的值?

下面是一个代码段

 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.

1 个答案:

答案 0 :(得分:2)

通过提供一个空数组作为效果的第二个参数,您已经告诉React永远不要重新创建此效果。因此它只发生一次,并且它关闭时具有的变量永远不会改变。

选项1:

您可以通过删除依赖项数组或使用您关心的变量填充它来重新运行效果。由于这将导致效果多次运行,因此您还需要提供清除功能以拆除先前的效果。

useEffect(() => {
  const callback = () => requestAnimationFrame(() => {
    setTest(test + 1);
  })
  window.addEventListener('scroll', callback);
  return () => window.removeEventListener('scroll', callback);
}) // <------

选项2:

由于您唯一需要刷新的是状态的最新值,因此可以使用setTest的回调版本。 React将为您传递最新的值,您可以根据此值计算更改。

您仍然希望具有拆解功能,以便在卸载此组件时可以删除侦听器:

useEffect(() => {
  const callback = () => requestAnimationFrame(() => {
    setTest(prev => prev + 1); // <------ 
  })
  window.addEventListener('scroll', callback);
  return () => window.removeEventListener('scroll', callback);
}, [])