前言
React Hooks的基本用法,官方文档[1] 已经非常详细。本文的目的,是想通过一个简单的例子详细分析一些令人疑惑的问题及其背后的原因。这是系列的第二篇,主要讲解 useEffect。
个人博客地址 🍹🍰 fe-code[2]
类生命周期
官方文档中说,可以将 useEffect 的回调和清理副作用的机制,类比成 class 组件中的生命周期。不过,由于 class 组件和函数组件自身特性不同的原因,导致这种类比也容易使人迷惑。
如果你熟悉 React class 的生命周期函数,你可以把 useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合。--使用 Effect Hook[3]
不过有时也容易出问题,就像我们一开始的定时器例子一样。
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
const id = setInterval(() => {
setCount(count + 1);
}, 1000);
}, []);
return <h1>{count}</h1>;
}
我们的需求很明确,就是在 componentDidMount 的时候,设置一个定时器。并且保证不会每次更新(componentDidUpdate)都重新设置。所以我们把第二个参数设置成[]
,来达到一样的效果。
当然这是有问题的,由于函数式组件执行方式的不同,我们在 useEffect 中拿到的 count 是闭包引用的,而每次更新又会是一个全新的执行上下文。这在上一篇文章中已经详细分析过。但是在 class 组件中,生命周期中的引用是这样的 this.state.count
,而且不同于函数式,