useEffect 懒创建清理函数

useEffect lazy created cleanup function

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

使用空 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;
}

这归结为以下问题:在正常的 class 组件中,willComponentUnmount 可以根据当前组件状态做出决定,但在 useEffect 的情况下,状态通过闭包传递给清理,如果状态已更改,以后将无法传递信息

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

The useRef() Hook isn’t just for DOM refs. The “ref” object is a generic container whose current property is mutable and can hold any value, similar to an instance property on a class. 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