在用Class制作组件时,经常会用生命周期函数,来处理一些额外的事情(副作用:和函数业务主逻辑关联不大,特定时间或事件中执行的动作,比如 Ajax 请求后端数据,添加登录监听和取消登录,手动修改DOM等等)。在React Hooks中也需要这样类似的生命周期函数,比如在每次状态(State)更新时执行,它为我们准备了useEffect。从本文开始来认识一下这个useEffect函数。
用Class的方式为计数器增加生命周期函数
为了让你更好的理解useEffect的使用,先用原始的方式把计数器的 Demo 增加两个生命周期函数componentDidMount和componentDidUpdate。分别在组件第一次渲染后在浏览器控制台打印出计数器结果和在每次计数器状态发生变化后打印出结果。代码如下:
import React, { Component } from 'react';
class Example3 extends Component {
constructor(props) {
super(props);
this.state = { count:0 }
}
componentDidMount(){
console.log(`ComponentDidMount=>You clicked ${this.state.count} times`)
}
componentDidUpdate(){
console.log(`componentDidUpdate=>You clicked ${this.state.count} times`)
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={this.addCount.bind(this)}>Chlick me</button>
</div>
);
}
addCount(){
this.setState({count:this.state.count+1})
}
}
export default Example3;
这就是在不使用 Hooks 情况下的写法,我们在浏览器中看一下效果:

那这段代码逻辑是什么?我们梳理一下:首先,我们声明了一个状态变量count,将它的初始值设为 0,然后我们告诉 react,我们的这个组件有一个副作用。给useEffecthook传了一个匿名函数,这个匿名函数就是我们的副作用。在这里我们打印了一句话,当然你也可以手动的去修改一个DOM元素。当 React 要渲染组件时,它会记住用到的副作用,然后执行一次。等 Reat 更新了 State 状态时,它再一词执行定义的副作用函数。
useEffect 两个注意点
- React 首次渲染和之后的每次渲染都会调用一遍
useEffect函数,而之前我们要用两个生命周期函数分别表示首次渲染(componentDidMonut)和更新导致的重新渲染(componentDidUpdate)。 - useEffect 中定义的函数的执行不会阻碍浏览器更新视图,也就是说这些函数时异步执行的,而
componentDidMonut和componentDidUpdate中的代码都是同步执行的。个人认为这个有好处也有坏处吧,比如我们要根据页面的大小,然后绘制当前弹出窗口的大小,如果是异步的就不好操作了。
总结
本文带大家初步认识了一下React Hooks中的useEffect函数,下篇文章我们继续学习useEffect的知识。