让我解释一下此代码的结果,以便轻松询问我的问题。
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()。
ForExample component
componentDidMount()
每当我更改名称输入时,都会记录“效果”和“清理”。反之亦然,自从我添加[username]到的第二个参数以来,每次更改用户名输入都不会记录任何消息useEffect()。这与componentDidUpdate()
[username]
useEffect()
componentDidUpdate()
最后,在ForExample component卸载时,将记录“清理”。这与有关componentWillUnmount()。
componentWillUnmount()
我们都知道。
总之,只要重新渲染组件(包括卸载),就会调用“清理”
如果要使该组件仅在卸载时记录“清理”,则只需将第二个参数更改useEffect()为[]。
[]
但是,如果我更改[username]为[],ForExample component将不再实现componentDidUpdate()for名称输入。
我要做的是使该组件componentDidUpdate()仅支持名称输入和componentWillUnmount()。(仅在卸载组件时记录“清理”)
由于清理操作不依赖于username,因此您可以将清理操作放在一个单独的对象中useEffect,该对象将空数组作为第二个参数。
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>