React useEffect 清理功能多次运行?

Jam*_*Lin 6 javascript reactjs react-hooks

在这里反应钩子菜鸟......

鉴于这个例子

useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    // Specify how to clean up after this effect:
    return function cleanup() {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });
Run Code Online (Sandbox Code Playgroud)

从文档

当组件卸载时,React 执行清理。但是,正如我们之前所了解的,效果在每次渲染时都会运行,而不仅仅是一次。这就是为什么 React 还会在下次运行效果之前清除上一次渲染中的效果。

这是否意味着unsubscribeFromFriendStatus仅在组件卸载或每次渲染时运行一次?

扩展我的问题:

ifunsubscribeFromFriendStatus每次都运行,而跳过它的唯一方法是使用可选的第二个参数……那么实现componentWillMountand的原始显式执行是不是更难了componentWillUnmount?说,我想subscribe什么时候componentWillMount,只unsubscribecomponentWillUnMount什么时候运行?

Jos*_* D. 5

这是否意味着unsubscribeFromFriendStatus仅在组件卸载或每次渲染时运行一次?

unsubscribeFromFriendStatus运行每次重新渲染

每次重新渲染,即使props.friend.id从未改变,它也会取消订阅和重新订阅。

要改善这一点,请仅在props.friend.id更改时运行效果。这可以通过将其作为依赖项添加到useEffect().

useEffect(
  () => { /* subscription */ }
  , [props.friend.id] // add as dependency
)
Run Code Online (Sandbox Code Playgroud)

是不是更难实现componentWillMount 和componentWillUnmount 的原始显式执行?比如说,我想在 componentWillMount 时订阅,并且只在 componentWillUnMount 时运行 unsubscribe?

使用 的旧值维护旧订阅是没有意义的props.friend.id

订阅使用资源(websocket 或观察者)。当取消订阅期间componentWillUnmount只是取消订阅您的props.friend.id.

旧订阅会怎样?没有被释放。因此,您有内存泄漏

  • @JamesLin 传递一个空数组 `[]` 只会在安装和卸载时运行效果。您可以在本节中阅读更多相关信息:https://reactjs.org/docs/hooks-reference.html#conditionally-firing-an-effect (2认同)