【问题标题】:useEffect lazy created cleanup functionuseEffect 懒惰创建的清理函数
【发布时间】:2019-10-01 04:49:31
【问题描述】:

我正在尝试创建使用副作用函数返回清理回调的效果的钩子。但是,我只想在卸载组件时调用它,而不是在重新渲染时调用它。

当你用空的 deps 数组调用 useEffect 时,正常的方法在这里不起作用,因为清理函数只在第一次调用钩子时创建一次。但是我的清理是稍后创建的,所以没有办法改变它。


function useListener(data) {
  const [response, updateResponse] = useState(null);

  useEffect(
    () => {
      if (data) {
        const removeListener = callRequest(data, resp => {
          updateResponse(resp);
        });

        return removeListener;
      }
    },
    [data]
  );

  return response;
}

这归结为以下问题:在普通类组件中,willComponentUnmount 可以根据当前组件状态做出决定,但在 useEffect 的情况下,状态通过闭包传递给清理,没有办法如果状态发生变化,稍后传递信息

【问题讨论】:

  • useEffect 定义了一种使您的组件对状态/道具更改做出反应的方法。与其考虑生命周期,不如用钩子来考虑什么状态可以导致运行效果。至少,这就是像 Dan Abramov 或 Ryan Florence 这样的 React 思想领袖一直在说的 :)
  • 是的,我知道,尽管我确实需要根据状态进行一次一次性清理,但我想不出办法
  • 组件卸载的原因是什么?只有data 不是undefined 的事实?

标签: reactjs react-hooks


【解决方案1】:

您可以使用useRef 来保存和更新您的回调函数

useRef() Hook 不仅仅适用于 DOM 引用。 “ref”对象是一个通用容器,其当前属性是可变的并且可以保存任何值,类似于类上的实例属性。 more

function useListener(data) {
  const [response, updateResponse] = useState(null);
  const cleanUpCallbackRef = useRef(() => {});

  useEffect(
    () => {
      if (data) {
        cleanUpCallbackRef.current = callRequest(data, resp => {
          updateResponse(resp);
        });
      }
    },
    [data]
  );

  useEffect(() => {
    return () => {
      cleanUpCallbackRef.current();
    }
  }, []);
  return response;
}

我创建一个简单的例子here

【讨论】:

  • 谢谢!这看起来正是我需要的。我没有想到 useRef,因为我在 DOM 的上下文中考虑过它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-07
  • 2020-04-09
  • 1970-01-01
  • 2019-10-28
  • 2017-02-15
  • 1970-01-01
  • 2012-02-20
相关资源
最近更新 更多