让我解释一下此代码的结果,以便轻松提出我的问题。
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()名称输入。
我想要做的是,让组件同时支持componentDidUpdate()名称输入和componentWillUnmount()。(仅在卸载组件时记录“已清理”)
您可以使用多个 useEffect()。
例如,如果我的变量是data1,我可以在我的组件中使用所有这些:
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"), [] );
由于清理不依赖于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>