React知识整理-生命周期

1/11/2020 React

react从入门到放弃

# 旧版生命周期


# 1. 初始化

初始化属性props和状态state

constructor(props) {
    super(props);
    this.state = { number: 0 }
    console.log('1.constructor构造函数')
}
1
2
3
4
5

# 2. 装载

//componentWillMount在渲染过程中可能会执行多次
componentWillMount() { // 取本地的数据 同步方式:采用渲染之前获取数据,只渲染一次
    console.log('2.组件将要加载 componentWillMount');
}
render() {
    console.log('3.render');
    return (
        <div>{this.state.number}</div>
    )
}
// 只会执行一次
componentDidMount() {
    console.log('4.组件挂载完成 componentDidMount');
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 3. 更新

属性更新props


componentWillReceiveProps(newProps) { // 第一次不会执行,之后属性更新时才会执行
    console.log('1 componentWillReceiveProps')
}
// react可以shouldComponentUpdate方法中优化 PureComponent 可以帮我们做这件事
shouldComponentUpdate(nextProps, nextState) {
    console.log('2 询问是否可以更新 shouldComponentUpdate')
    return nextProps.n % 3 == 0; //子组件判断接收的属性 是否满足更新条件 为true则更新
}

componentWillUpdate() {
    console.log('3 组件将要更新 componentWillUpdate');
}
render() {
    console.log('4 render');
    return (
        <div>{this.props.number}</div>
    )
}
componentDidUpdate() {
    console.log('5 组件完成更新 componentDidUpdate');
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

状态更新states

// 触发更新操作
handleClick = () => {
    this.setState({ number: this.state.number + 1 });
};

// react可以shouldComponentUpdate方法中优化 PureComponent 可以帮我们做这件事
shouldComponentUpdate(nextProps, nextState): boolean { // 代表的是下一次的属性 和 下一次的状态
    console.log('1 组件是否更新 shouldComponentUpdate');
    return nextState.number % 2 == 0;
    // return nextState.number!==this.state.number; //如果此函数种返回了false 就不会调用render方法了
} //不要随便用setState 可能会死循环

componentWillUpdate() {
    console.log('2 组件将要更新 componentWillUpdate');
}
render() {
    console.log('3 render');
    return (
        <div>{this.state.number}</div>
    )
}
componentDidUpdate() {
    console.log('4 组件完成更新 componentDidUpdate');
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 4. 卸载

componentWillUnmount(){
    console.log('组件卸载');
}
1
2
3

# 新版生命周期


  • 去除三个生命周期:componentWillUpdate、componentWillMount、componentWillReceiveProps
  • 新增:getDerivedStateFromProps、getSnapshotBeforeUpdate

# 1、getDerivedStateFromProps

根据传入的属性props派生到状态对象state 静态方法,必须加static

import React, { Component } from 'react'

export default class Counter extends Component {
    constructor() {
        super();
        this.state = {number:0};
    }
    add = ()=>{
        this.setState({number:this.state.number+1});
    }
    render() {
        return (
            <div>
                <p>{this.state.number}</p>
                <button onClick={this.add}>+</button>
                <SubCounter number={this.state.number}/>
            </div>
        )
    }
}
class SubCounter extends Component {
    constructor(){
        super();
        this.state = {number:0};
    }
    //getDerivedStateFromProps() is defined as an instance method and will be ignored. Instead, declare it as a static method
    //根据新的属性对象派生状态对象 新的属性对象 和旧的状态对象
    static getDerivedStateFromProps(nextProps,prevState){
        if(nextProps.number%2==0){
            return {number:prevState.number+nextProps.number*2};
        }else{
            return {number:prevState.number+nextProps.number*3};
        }
    }
    render() {
        return (
            <div>
                {this.state.number} {this.state.date}
            </div>
        )
    }
}
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42

# 2、getSnapshotBeforeUpdate

获取更新前的快照,然后传递给componentDidUpdate的第三个参数。

import React, { Component } from 'react'

export default class GetSnapshotBeforeUpdate extends Component {
  constructor(props){
    super(props);
    this.wrapper = React.createRef();
    this.state = {messages:[]};
  }
  componentDidMount(){
      setInterval(()=>{
        this.setState({messages:["msg:"+this.state.messages.length,...this.state.messages]});
        //this.setState({messages:[...this.state.messages,this.state.messages.length]});
      },1000);
  }
  getSnapshotBeforeUpdate(){
      //返回更新内容的高度 300px
    return this.wrapper.current.scrollHeight;
  }
  //组件更新完毕
  componentDidUpdate(prevProps,prevState,prevScrollHeight){
    this.wrapper.current.scrollTop = this.wrapper.current.scrollTop+(this.wrapper.current.scrollHeight-prevScrollHeight);
  }
  render() {
    let style = {
        height:'100px',
        width:'200px',
        border:'1px solid red',
        overflow:'auto'
    }
    return (
      <ul style={style} ref={this.wrapper}>
        {
            this.state.messages.map((message,index)=><li key={index}>{message}</li>)
        }
      </ul>
    )
  }
}

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
29
30
31
32
33
34
35
36
37
38
39
Last Updated: 1/13/2020, 7:38:12 AM
    asphyxia
    逆时针向