当前位置: 首页 > 面试题库 >

反应钩useEffect()清理仅componentWillUnmount吗?

徐承载
2023-03-14
问题内容

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

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()

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

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

我们都知道。

总之,只要重新渲染组件(包括卸载),就会调用“清理”

如果要使该组件仅在卸载时记录“清理”,则只需将第二个参数更改useEffect()[]

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

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


问题答案:

由于清理操作不依赖于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>


 类似资料: