我已经阅读了关于Hooks的React Docs,我很困惑。什么时候调用useEffect Hook清理函数?

时间:2019-04-16 16:09:52

标签: javascript reactjs react-hooks

关于何时调用useEffect清理函数的react docs解释令人困惑,并且说实话一般。 他们甚至通过将类思维模型与钩子进行比较来使您更加困惑。基于类的组件的工作方式不同于带有钩子的基于函数的组件。 React会记住您提供给useEffect的effect函数,并在将更改刷新到可以理解的DOM后运行它。 现在,如何以及何时调用返回的函数(“清理函数”)?

下面的代码示例:

import React, { useState, useEffect } from 'react';

function FriendStatus(props) {
  const [isOnline, setIsOnline] = useState(null);

  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);
    };
  });

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}

2 个答案:

答案 0 :(得分:4)

当作为第二个参数给定的数组中的任何元素发生更改时,或在未提供第二个参数的情况下每次渲染时,或者当组件为卸载。

示例

useEffect
const { useEffect, useState } = React;

function MyComponent({ prop }) {
  useEffect(() => {
    console.log('Effect!');
    return () => console.log('Cleanup!')
  }, [prop])

  return (
    <div>{prop}</div>
  );
}

function App() {
  const [value, setValue] = useState(0);

  useEffect(() => {
    setInterval(() => {
      setValue(value => value + 1);
    }, 1000)
  }, [])

  return value < 3 ? <MyComponent prop={value} /> : null;
}

ReactDOM.render(<App />, document.getElementById("root"));

答案 1 :(得分:1)

在不使用第二个参数的情况下,它将在每次渲染时被调用。

这通常是多余的,因此即使第二个参数为空[],使用第二个参数也是个好主意。

例如

useEffect(() => {....}, []);

执行上述操作仅在组件与DOM物理分离时才调用清除。

您也可以通过props而不是[],这很方便,如果说要更改道具,例如您所在的聊天室,它将清理当前的聊天室,并初始化新的聊天室聊天室等

因此,在您的示例中,传递[props.friend.id]是有道理的,因为如果ID发生更改,则有必要调用清除操作,然后为新的ID重新运行效果。