来自React docs:
如果你熟悉 React 类生命周期方法,你可以想
useEffect Hook 为 componentDidMount、componentDidUpdate 和
componentWillUnmount 组合。
他们的意思是:
componentDidMount 有点像useEffect(callback, [])
componentDidUpdate 有点像useEffect(callback, [dep1, dep2, ...]) - deps 数组告诉 React:“如果其中一个 deps 发生变化,则在渲染后运行回调”。 p>
componentDidMount + componentDidUpdate 有点像useEffect(callback)
componentWillUnmount 是回调中返回的函数:
useEffect(() => {
/* some code */
return () => {
/* some code to run when rerender or unmount */
}
)
借助Dan Abramov 他的blog 的措辞以及我自己的一些补充:
虽然您可以使用这些钩子,但它并不是完全等价的。与componentDidMount 和componentDidUpdate 不同,它将捕获 道具和状态。因此,即使在回调内部,您也会看到特定渲染的道具和状态(这意味着在componentDidMount 中是初始道具和状态)。如果您想查看“最新”的内容,可以将其写入 ref。但是通常有一种更简单的方法来构建代码,这样您就不必这样做了。
返回的函数应该是componentWillUnmount 的替代函数,也不是完全等价的,因为该函数将在每次组件重新渲染和组件卸载时运行。
请记住,效果的心理模型与组件的生命周期不同,试图找到它们的确切等价物可能会让您感到困惑,而不是帮助。为了提高工作效率,您需要“思考效果”,他们的心智模型更接近于实现同步,而不是响应生命周期事件。
来自 Dan 博客的示例:
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
setTimeout(() => {
console.log(`You clicked ${count} times`);
}, 3000);
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
如果我们使用类实现:
componentDidUpdate() {
setTimeout(() => {
console.log(`You clicked ${this.state.count} times`);
}, 3000);
}
this.state.count 始终指向最新计数,而不是属于特定渲染的计数。