useEffect 是 React Hooks 的核心,要保证理解它的运行机制和正确的使用方法才能避免这样那样的坑。在以前的工作中,因为它我碰到过无数个坑,比如拿到的值是旧的,该执行的时候不执行,不该执行的时候执行了……
所以为了避免如上尴尬、节省绞尽脑汁找 bug 的时间、保护咱们的发际线,一定要认真学会如何正确使用 useEffect hook。
什么是 Effect
俗话说,知已知彼,百战不殆,我们先了解下神马是 Effect。其实大家在开发过程中或多或少的都接触过 side effect 的概念,即副作用 —— 对于数据抓取,注册监听事件,修改 DOM 元素等马后炮式的操作都属于副作用,因为我们渲染出来的页面是静态的,任何在之后的操作都会对它产生影响,所以才称之为副作用。而 useEffect
则是专门用来编写副作用代码的,这也是 React 的核心所在。
与生命周期的关系
目前市面上的文章,包括官方文档都让我们把 useEffect
想象成 componentDidMount
, componentDidUpdate
,componentWillUnmount
三个生命周期的结合体。其实并不然,如果非要把 useEffect
的运行机制往生命周期上靠,会造成一些逻辑上的困惑,进而产生 bug。我们所要做的,就是把 useEffect
当成一个全新的特性,专门为函数式组件服务的,这样用起来才不会迷茫。下面我们通过实例来演示它的各种用法。
运行时机
useEffect
必然会在 render 的时候执行一次,其他的运行时机取决于以下情况:
- 有没有第二个参数。
useEffect
hook 接受两个参数,第一个是要执行的代码,第二个是一个数组,指定一组依赖的变量,其中任何一个变量发生变化时,此 effect 都会重新执行一次。 - 有没有返回值。
useEffect
的执行代码中可以返回一个函数,在每一次新的 render 进行前或者组件 unmount 之时,都会执行此函数,进行清理工作。
我们先看一个简单的例子,想看完整代码和随意把玩的,请点击下边按钮
我们首先看最顶层 <App />
的代码:
function App() {
const [showList, setShowList] = useState(false);
const [postCount, setPostCount] = useState(5);
return (
<div className="App">
<button onClick={
() => setShowList(!showList)}>
{
showList ? "隐藏" : "显示"}
</button>
<button onClick={
() => setPostCount(previousCount => previousCount + 1)}>
增加数量
</button>
{
showList && <PostList count={
postCount} />}
</div>
);
}
此组件用来显示一系列的文章列表,以及控制文章列表是否显示的按钮和控制显示多少条文章的按钮。我们用 showList
state 来控制 <PostList />
的显示与否。这是为了让 <PostList />
组件 unmount 再 render ,以证明每次它 render 和 unmount 的时候,useEffect
hook 都会跑一次。 <PostList />
组件的代码如下:
function PostList(