React useEffect清理功能运行多次?

时间:2019-10-17 03:27:38

标签: 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);
    };
  });

来自文档

  

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

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

扩展我的问题:

如果unsubscribeFromFriendStatus每次都运行,并且跳过它的唯一方法是使用可选的第二个参数...那么,这样做不会更难实现componentWillMount的原始显式执行和componentWillUnmount?假设我想在subscribecomponentWillMount,并且仅在unsubscribe时运行componentWillUnMount

1 个答案:

答案 0 :(得分:4)

  

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

unsubscribeFromFriendStatus运行每次重新渲染

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

要改善此效果,请仅在props.friend.id更改时运行效果 。 可以通过将其添加为对useEffect()的依赖来实现。

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

难道不是很难实现componentWillMount和componentWillUnmount的原始显式执行吗?说,我想在componentWillMount时订阅,而仅在componentWillUnMount时运行取消订阅?

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

订阅使用资源(网络套接字或观察者)。在componentWillUnmount期间取消订阅只是取消订阅props.friend.id的最新值。

旧版订阅会如何处理?未释放。 因此,您有内存泄漏