反应钩子useEffect()清理仅用于componentWillUnmount?

新手上路,请多包涵

让我解释一下这段代码的结果,以便轻松地询问我的问题。

 const ForExample = () => {
    const [name, setName] = useState('');
    const [username, setUsername] = useState('');

    useEffect(() => {
        console.log('effect');
        console.log({
            name,
            username
        });

        return () => {
            console.log('cleaned up');
            console.log({
                name,
                username
            });
        };
    }, [username]);

    const handleName = e => {
        const { value } = e.target;

        setName(value);
    };

    const handleUsername = e => {
        const { value } = e.target;

        setUsername(value);
    };

    return (
        <div>
            <div>
                <input value={name} onChange={handleName} />
                <input value={username} onChange={handleUsername} />
            </div>
            <div>
                <div>
                    <span>{name}</span>
                </div>
                <div>
                    <span>{username}</span>
                </div>
            </div>
        </div>
    );
};

ForExample component 挂载时,将记录“效果”。这与 componentDidMount() 相关。

每当我更改名称输入时,都会记录“效果”和“清理”。反之亦然,每当我更改用户名输入时,都不会记录任何消息,因为我将 --- 添加到 --- useEffect() [username] 的第二个参数。这与 componentDidUpdate() 有关

最后,当 ForExample component 卸载时,将记录“清理”。这与 componentWillUnmount() 相关。

我们都知道。

总而言之,每当重新渲染组件时都会调用“清理”(包括卸载)

如果我想让这个组件仅在卸载时记录“清理”,我只需将 useEffect() 的第二个参数更改为 []

但是,如果我将 [username] 更改为 []ForExample component 不再实现 componentDidUpdate() 输入

我想要做的是,使组件支持 componentDidUpdate() 仅用于名称输入和 componentWillUnmount() 。 (仅在卸载组件时记录“清理”)

原文由 koo 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 475
2 个回答

由于清理不依赖于 username ,因此您可以将清理放在单独的 useEffect 中,该数组将空数组作为第二个参数。

例子

 const { useState, useEffect } = React;

const ForExample = () => {
  const [name, setName] = useState("");
  const [username, setUsername] = useState("");

  useEffect(
    () => {
      console.log("effect");
    },
    [username]
  );

  useEffect(() => {
    return () => {
      console.log("cleaned up");
    };
  }, []);

  const handleName = e => {
    const { value } = e.target;

    setName(value);
  };

  const handleUsername = e => {
    const { value } = e.target;

    setUsername(value);
  };

  return (
    <div>
      <div>
        <input value={name} onChange={handleName} />
        <input value={username} onChange={handleUsername} />
      </div>
      <div>
        <div>
          <span>{name}</span>
        </div>
        <div>
          <span>{username}</span>
        </div>
      </div>
    </div>
  );
};

function App() {
  const [shouldRender, setShouldRender] = useState(true);

  useEffect(() => {
    setTimeout(() => {
      setShouldRender(false);
    }, 5000);
  }, []);

  return shouldRender ? <ForExample /> : null;
}

ReactDOM.render(<App />, document.getElementById("root"));
 <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>

原文由 Tholle 发布,翻译遵循 CC BY-SA 4.0 许可协议

您可以使用多个 useEffect()。

例如,如果我的变量是 data1 ,我可以在我的组件中使用所有这些:

 useEffect( () => console.log("mount"), [] );
useEffect( () => console.log("data1 update"), [ data1 ] );
useEffect( () => console.log("any update") );
useEffect( () => () => console.log("data1 update or unmount"), [ data1 ] );
useEffect( () => () => console.log("unmount"), [] );

原文由 Mehran Motiee 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进