再用class写组件时,经常会用到生命周期函数,来处理一些额外的事情(副作用:和函数业务主逻辑关联不大,特定时间或事件中执行的动作,比如请求后端数据,修改Dom等)在React HookS中也需要类似的生命周期函数,useEffect由此诞生。
由class的形式,声明一个组件,并增加两个生命周期函数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;
用React Hooks的形式实现上面同样的功能
import React, { useState , useEffect } from 'react';
function Example(){
const [ count , setCount ] = useState(0);
//---关键代码---------start-------
useEffect(()=>{
console.log(`useEffect=>You clicked ${count} times`)
})
//---关键代码---------end-------
return (
<div>
<p>You clicked {count} times</p>
<button onClick={()=>{setCount(count+1)}}>click me</button>
</div>
)
}
export default Example;
Effect的两个注意点:
1.React首次渲染和之后的每次渲染都会调用一遍useEffect函数,而之前我们要用两个生命周期函数分别表示首次渲染(componentDidMount)和更新导致的重新渲染(ComponentDidUpdate)
2.useEffect中定义的函数的执行不会阻碍浏览器更新视图,也就是说这些函数是异步执行的,而componentDidMount和componentDidUpdate中的代码都是同步执行的。如果我么你要根据页面的大小然后绘制出当前弹出窗口的大小,异步的就不太好控制了。
用useEffect实现componentWillUnmount生命周期函数
主要就是用到了useEffect的第二个参数,它是一个数组,数组中可以写入很多状态对应的变量,意思是当状态值发生变化时,我们才进行解绑。但是当传空数组[]时,就是当组件将被销毁时才进行解绑,这也就实现了componentWillUnmount的生命周期函数。
最后分享一下阮一峰的一篇文章
“轻松学会 React 钩子:以 useEffect() 为例”
http://www.ruanyifeng.com/blog/2020/09/react-hooks-useeffect-tutorial.html