React组件的生命周期
Axin Lv1

旧版生命周期

react生命周期(旧)

旧版生命周期主要使用以下钩子:

挂载时

  • constructor

    组件构造函数,常用于初始化组件state,以及对组件内响应方法的绑定

  • componentWillMount

    在第一次渲染前的钩子函数,也常用于初始化state,在新版生命周期中已弃用

  • render

    组件渲染函数,返回一个jsx元素,用于显示真实DOM中的元素

  • componentDidMount

    在组件挂载后执行,常用于设置定时器

更新时

  • compontentWillReceiveProps

    在父组件更新时会触发此函数,在此函数中可以根据props是否变化来setState,并且在此函数中的setState不会再次触发子组件的render

  • shouldComponentUpdate

    setStatecompontentWillReceiveProps后会触发此函数,可以在此函数中编写相关方法判断是否继续render,相当于一个自定义的diff函数

  • componentWillUpdate

    在组件的propsstate发生改变后,render之前触发,在第一次组件挂载时不会触发此函数

  • render

  • componentDidUpdate

    在组件的propsstate更新完并执行完render后触发

卸载时

  • componentWillUnmount

    在组件卸载或者销毁之前触发

其中componentWillMountcompontentWillReceivePropscomponentWillUpdate在新版生命周期中均已被弃用

新版生命周期

react生命周期(新)

新版生命周期中将较于旧版,增加了两个新的钩子,分别是getDerivedStateFromPropsgetSnapshotBeforeUpdate,并弃用了componentWillMountcompontentWillReceivePropscomponentWillUpdate这三个钩子

  • static getDerivedStateFromProps(nextProps, prevState)

    getDerivedStateFromProps为静态函数,传入参数为nextPropsprevState。其中,nextProps为将要更新的props,prevState为上一个状态,可根据传入的props,以及过去的state来增加限制条件,防止无用的更新

  • getSnapshotBeforeUpdate(prevProps, prevState)

    在组件更新DOM前调用,可以在此DOM更新前捕获一些页面信息(例如滚动位置),此生命周期返回的值会作为参数传入componentDidUpdate

getSnapshotBeforeUpdate使用案例

getSnapshotBeforeUpdate常用于获取DOM更新前的页面信息,在此编写一个页面新闻流组件,来演示getSnapshotBeforeUpdate的用法

页面新闻流

如图所示,在页面中新闻每秒新增一条,当新闻条数充满div的时候会出现右侧滑动条,并且期望新出的新闻不会改动滑动条当前滑动位置。

我们可以通过getSnapshotBeforeUpdate函数在页面更新时,获取当前可滑动区域高度信息并return,在componentDidUpdate中可获取此高度,并将新的滑动区域高度与旧的高度相减,得到滑动条高度的变化量,以此设置scrollTop的值。具体代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class NewsList extends React.Component{
constructor(props) {
super(props)
this.state = {newsArr:[]}
setInterval(()=>{
let {newsArr} = this.state
let news = "新闻" + (newsArr.length+1)
this.setState({newsArr: [news, ...newsArr]})
}, 1000)
}
getSnapshotBeforeUpdate(){
return this.refs.list.scrollHeight
}
componentDidUpdate(preProps, preState, height){
this.refs.list.scrollTop += this.refs.list.scrollHeight-height
}
render(){
return (
<div className="list" ref="list">
{
this.state.newsArr.map((n, index)=>{
return <div className="news" key={index}>{n}</div>
})
}
</div>
)
}
}

总结

在总体上,新旧生命周期的区别不大,新的生命周期新增的getDerivedStateFromPropsgetSnapshotBeforeUpdate钩子可替代旧版生命周期相关弃用函数。此外新版生命周期增加了更多约束,防止开发者乱来,使得代码运行效率降低。

  • 本文标题:React组件的生命周期
  • 本文作者:Axin
  • 创建时间:2021-11-15 16:14:31
  • 本文链接:https://izhang.xin/2021/11/15/react生命周期/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!