生命周期:组件从诞生到销毁会经历一系列的过程,该过程就叫做声明周期。React在组件的声明周期中提供了一系列的钩子函数(类似于事件),可以让开发者在函数中注入代码,这些代码会在适当的时候运行。
生命周期仅存在于类组件中,函数组件每次调用都是重新运行函数,旧的组件即刻被销毁
旧版生命周期
React < 16.0.0 . 官方已经不推荐使用旧版了,因为有一些问题不能解决。但我们仍要学习卸载是unmount
一、constructor:初始化阶段
- 同一个组件对象,只会创建一次,因此该函数只会运行一次
- 不能在组件第一次挂载到页面之前调用setState,为了避免问题,构造函数中严禁使用setState
二、componentWillMount:组件即将挂载到页面上
- 正常情况下,和构造函数一样,它只会运行一次
- 可以使用setState,但是为了避免bug,不要在这里使用。因为在某些特殊情况下,该函数可能被调用多次(比如:服务端ssr、以及在初始化阶段可能会把生命周期打断导致cwm等重新运行)
三、render
- 返回一个虚拟DOM,会被挂载到虚拟DOM中,它最终会被渲染到页面的真实DOM中
- render可能不止运行一次,只需要重新渲染,就会重新运行
- 严禁在render中调用setState(因为可能会导致无限递归渲染)
四、componentDidMount:在它调用之前,虚拟DOM已经成为真实DOM且挂载到页面中了
- 只会执行一次
- 可以使用setState
- 通常情况下,会将网络请求,启动计时器等一开始需要的操作,书写到该函数中
五、至此,组件完成挂载阶段,进入活跃状态,开始等待(等什么呢?等需要重新渲染的时候—>属性/状态变化)
六、componentWillRecieveProps:属性发生变化(指的是属性重新被赋值,内容不一定变)时就会触发该函数
- 即将接受新的属性值
- 参数为新的属性对象
- 该函数可能会导致一些bug,新版已移除,故不推荐使用
七、shouldComponentUpdate:状态发生变化或者cwrp完成后会触发该钩子函数,是一个性能优化点
- 指示React是否要重新渲染该组件,通过返回true或false来指定
- 默认情况下会直接返回true(也就是不写该函数时)
该函数有两个参数,第一个是nextProps,第二个是nextState
//性能优化
if(this.props.n===nextProps.n && this.state.n===nextState.n){
return false;
}
如果指定始终返回false,则会导致状态与UI不一致,因为没有真正地去更新DOM
八、componentWillUpdate:组件即将被重新渲染(必须上一步scu返回的是true才会触发)
九、render:职责同上述render一致
十、componentDidUpdate:组件已经完成重新渲染,然后调用该函数
- 该函数第一个参数是之前的属性,第二个参数是之前的状态
- 往往在该函数中使用DOM操作,改变元素
十一、至此更新阶段完成
十二、componentWillUnmount:组件即将被卸载,组件从虚拟DOM中移除后触发(我猜测是这样的)?
- 通常在该函数中,销毁一些组件依赖的资源,比如计时器
- 在componentWillUnmount中setState是一定成功的,但由于组件即将被卸载,你的setState并不会再次触发组件的render函数,因此出现了state和render函数中不同步的问题。我在用react-navigation的goback的时候,发现之前的页面被重置的state并没有被同步过去
新版生命周期
React >= 16.0.0
React官方认为:某个数据的来源必须是单一的,要让数据的拥有者改变数据
这里卸载应是unmount,上面打错了
主要有下述不同,其他同旧版一致
移除了:
componentWillMount(因为可能调用多次,导致很多bug)
componentWillRecieveProps(反模式:它可能造成数据来源不单一,父亲儿子都可影响,这就会出现bug)componentWillUpdate(主要是因为没啥用,意义不大)
新增了:
一、static getDerivedStateFromProps(从属性中获取新的状态,其实绝大部分下用不到)
- 该函数几乎没啥用,就是为了告诉你坚决反对 componentWillRecieveProps
- 在constructor之后,props或state变化后,(首次渲染或更新的)render前,调用该函数
- 它调用完了:若是更新阶段,就会调用 shouldComponentUpdate ,再调用render;
若是首次渲染阶段,则会调用render
- 通过参数可以获取新的属性和当前状态(即nextProps, currentState)
- 该函数的返回值(必须写null or object)会覆盖掉组件状态,不写这个函数则默认返回null(应该是这样)
- 该函数是静态的
二、getSnapshotBeforeUpdate(获取更新前的快照)
- 处于更新流程时 且 在render之后,componentDidUpdate之前调用该函数
- 执行时机:真实的DOM构建完成,但还未实际渲染到页面中(因为JS主线程与UI线程互斥)
- 在该函数中,通常用于实现一些附加到DOM操作—比如滚动条效果等
- 通过参数可以获取更新前的属性和状态,第一个参数是prevProps,第二个参数是prevState
- 该函数的返回值(必须是有效的值)会作为 componentDidUpdate 的第三个参数