React 生命周期

Posted lyt0207

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React 生命周期相关的知识,希望对你有一定的参考价值。

一、旧版:

技术图片

1、initialization

初始化属性和状态

2、Mounting (加载阶段:涉及3个钩子函数)

2.1 componentWillMount()

组件加载时只调用,以后组件更新不调用,整个生命周期只调用一次,此时可以修改state

2.2 render()

react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行

2.3 componentDidMount()

组件渲染之后调用,只调用一次

3、Updating(更新阶段:涉及5个钩子函数)

3.1 componentWillReceivePorps(nextProps)

组件加载时不调用,组件接受新的props时调用

3.2 shouldComponentUpdate(nextProps, nextState)

组件接收到新的props或者state时调用,return true就会更新dom(使用diff算法更新),return false能阻止更新(不调用render)

3.3 componentWillUpdata(nextProps, nextState)

组件加载时不调用,只有在组件将要更新时才调用,此时可以修改state

3.4 render()

react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行

3.5 componentDidUpdate()

组件加载时不调用,组件更新完成后调用

4、Unmounting(卸载阶段:涉及1个钩子函数)


4.1 componentWillUnmount()

组件渲染之后调用,只调用一次

基本用法:
import React from "react";
import ReactDOM from "react-dom";

/**
 * 只有类组件才有生命周期
 * 
 */
class App extends React.Component{
  static defaultProps = { //设置默认属性
    name:‘leah‘
  }
  constructor(props) {
    super(props)
    this.state = {count: 0}
    console.log(‘1.执行构造函数,设置初始状态‘)
  }
  //1.挂载
  componentWillMount(){
    console.log(‘1.1组件将要挂载到页面上‘)
  }
  handleClick = () =>{
    this.setState({count: this.state.count +1})
  }
  render() {
    console.log(‘1.2.返回虚拟dom‘)
    return (
      <div>
        <p>{this.state.count}</p>
        <button onClick={this.handleClick}>+</button>
        {/* <ChildCounter count={this.state.count}></ChildCounter> */
            this.state.count < 3 ? <ChildCounter count={this.state.count}></ChildCounter> : null //当count>3的时候讲子组件销毁
        }
      </div>
    )
  }
  //当虚拟dom被挂载到真实dom上之后才执行这个,这个时候才能获取到真实dom
  componentDidMount(){
    console.log(‘1.3.组件已经挂载到了页面上‘)
  }
  //2.更新
  //2.1询问组件状态是否更新
  shouldComponentUpdate(nextprops,nextState){
    console.log(‘2.1 询问组件状态是否更新‘)
    // return nextState.count % 3 === 0 //表示如果state是3的倍数就更新,否则就不更新
    return true
  }
  componentWillUpdate(){ 
    console.log(‘2.2组件状态将要更新‘)
  }
  componentDidUpdate(){
    console.log(‘2.2组件状态已经更新‘)
  }

}
class ChildCounter extends React.Component{
  componentWillReceiveProps(newprops){ //组件属性的更新多了这一步
    console.log(‘组件将要接收新的属性‘,newprops)
  }
  shouldComponentUpdate(nextprops,nextState){
    console.log(‘询问子组件属性是否更新‘)
    // return nextprops.count % 6 === 0 //表示如果state是3的倍数就更新,否则就不更新
    return true
  }
  componentWillUpdate(){
    console.log(‘子组件属性将要更新‘)
  }
  componentDidUpdate(){
    console.log(‘子组件属性已经更新‘)
  }
  componentWillUnmount(){
    console.log(‘子组件将要被销毁‘)
  }
  render(){
    console.log(‘childCounter render‘)
    return(
    <div>{this.props.count}</div>
    )
  }
}
ReactDOM.render(<App></App>,document.getElementById(‘root‘))
/**
 * componentWillMount 先父后子 
 * componentDidMount 先子后父
 */

 二、新版生命周期

技术图片

 

1、 Mounting(加载阶段:涉及4个钩子函数)

1.1 constructor()

加载的时候调用一次,可以初始化state

1.2 static getDerivedStateFromProps(props, state)

组件每次被rerender的时候,包括在组件构建之后(虚拟dom之后,实际dom挂载之前),每次获取新的props或state之后;每次接收新的props之后都会返回一个对象作为新的state,返回null则说明不需要更新state;
配合componentDidUpdate,可以覆盖componentWillReceiveProps的所有用法

1.3 render()

react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行

1.4 componentDidMount()

组件渲染之后调用,只调用一次

2、Updating(更新阶段:涉及5个钩子函数)

2.1 static getDerivedStateFromProps(props, state)

组件每次被rerender的时候,包括在组件构建之后(虚拟dom之后,实际dom挂载之前),每次获取新的props或state之后;每次接收新的props之后都会返回一个对象作为新的state,返回null则说明不需要更新state;配合componentDidUpdate,可以覆盖componentWillReceiveProps的所有用法

2.2 shouldComponentUpdate(nextProps, nextState)

组件接收到新的props或者state时调用,return true就会更新dom(使用diff算法更新),return false能阻止更新(不调用render)

2.3 render()

react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行

2.4 getSnapshotBeforeUpdate(prevProps, prevState)

触发时间: update发生的时候,在render之后,在组件dom渲染之前;返回一个值,作为componentDidUpdate的第三个参数;配合componentDidUpdate, 可以覆盖componentWillUpdate的所有用法

2.5 componentDidUpdate()

组件加载时不调用,组件更新完成后调用

3、Unmounting(卸载阶段:涉及1个钩子函数)

3.1 componentWillUnmount()

组件渲染之后调用,只调用一次
基本用法:
import React from "react";
import ReactDOM from "react-dom";

/**
 * 新的生命周期函数去掉了三个:
 * componentWillReceiveProps componentWillUpdate componentWillMount
 * 多了两个:getDerivedStateFromProps  
 * 
 */
class App extends React.Component{
  static defaultProps = { //设置默认属性
    name:‘leah‘
  }
  constructor(props) {
    super(props)
    this.state = {count: 0}
    console.log(‘1.执行构造函数,设置初始状态‘)
  }
  //1.挂载
  handleClick = () =>{
    this.setState({count: this.state.count +1})
  }
  render() {
    console.log(‘1.2.返回虚拟dom‘)
    return (
      <div>
        <p>{this.state.count}</p>
        <button onClick={this.handleClick}>+</button>
        <ChildCounter count={this.state.count}></ChildCounter> 
      </div>
    )
  }
  //当虚拟dom被挂载到真实dom上之后才执行这个,这个时候才能获取到真实dom
  componentDidMount(){
    console.log(‘1.3.组件已经挂载到了页面上‘)
  }
  //2.更新
  //2.1询问组件状态是否更新
  shouldComponentUpdate(nextprops,nextState){
    console.log(‘2.1 询问组件状态是否更新‘)
    // return nextState.count % 3 === 0 //表示如果state是3的倍数就更新,否则就不更新
    return true
  }
  componentDidUpdate(){
    console.log(‘2.2组件状态已经更新‘)
  }

}
class ChildCounter extends React.Component{
  state = {name: ‘leah‘, count: 0}
  shouldComponentUpdate(nextprops,nextState){
    console.log(‘询问子组件属性是否更新‘)
    // return nextprops.count % 6 === 0 //表示如果state是3的倍数就更新,否则就不更新
    return true
  }
  componentDidUpdate(){
    console.log(‘子组件属性已经更新‘)
  }
  componentWillUnmount(){
    console.log(‘子组件将要被销毁‘)
  }
  //每当状态属性变更的时候执行此方法,可以得到最新的属性和状态
  //nextProps 代表新的属性对象 prevState 代表旧的状态对象
  static getDerivedStateFromProps(nextProps, prevState){
    if( nextProps.count % 2 === 0) {
      return {count : nextProps.count * 2}
    }else {
      return {count : nextProps.count * 3}
    }
  }
  render(){
    console.log(‘childCounter render‘)
    return(
    <div>{this.state.count}</div>
    )
  }
}

ReactDOM.render(<App></App>,document.getElementById(‘root‘))
/**
 * componentWillMount 先父后子 
 * componentDidMount 先子后父
 */

总结:

  • React16新的生命周期弃用了componentWillMount、componentWillReceivePorps,componentWillUpdate
  • 新增了getDerivedStateFromProps、getSnapshotBeforeUpdate来代替弃用的三个钩子函数(componentWillMount、componentWillReceivePorps,componentWillUpdate)
  • React16并没有删除这三个钩子函数,但是不能和新增的钩子函数(getDerivedStateFromProps、getSnapshotBeforeUpdate)混用,React17将会删除componentWillMount、componentWillReceivePorps,componentWillUpdate
  • 新增了对错误的处理(componentDidCatch)
https://zhuanlan.zhihu.com/p/38030418 这篇文章有点内容

 

 

 

以上是关于React 生命周期的主要内容,如果未能解决你的问题,请参考以下文章

关于片段生命周期

调用 replace() 时片段的生命周期是啥?

Android片段生命周期:onResume调用了两次

在不存在的片段上调用片段生命周期和 onCreate 的问题

导航上的片段生命周期重叠

Android 片段生命周期