# React生命周期(旧)

# 零、react的生命周期函数

  • 组件将要挂载时触发的函数:componentWillMount
  • 组件挂载完成时触发的函数:componentDidMount
  • 是否要更新数据时触发的函数:shouldComponentUpdate
  • 将要更新数据时触发的函数:componentWillUpdate
  • 数据更新完成时触发的函数:componentDidUpdate
  • 组件将要销毁时触发的函数:componentWillUnmount
  • 父组件中改变了props传值时触发的函数:componentWillReceiveProps

react v16.0前生命周期的更新图:

react v16.0前生命周期的更新图

# 一、组件初始化

然后是初始化,也就是以下代码中类的构造方法 constructor() , PickerDemo 类继承了 react Component 这个基类,也就继承这个 react 的基类,才能有 render() ,生命周期等方法可以使用,这也说明为什么函数组件不能使用这些方法的原因。

super(props) 用来调用基类的构造方法 constructor() , 也将父组件的 props 注入给子组件,功子组件读取(组件中 props 只读不可变,state 可变)。 而 constructor() 用来做一些组件的初始化工作,如定义 this.state 的初始内容。

# 二、挂载部分

根据官方生命周期图我们可以看到,一个组件的加载渲染,首先是 defaultPropspropsTypes ;

然后就是 constructorthis.state 里的初始数据,所以到这里是第一步。接着就是 componentWillMount 组件将要开始挂载了,这是第二步。然后组件挂载,render 解析渲染,所以第三步呼之欲出,就是render数据都渲染完成,最后 componentDidMount 组件挂载完成。

import React ,{Component} from 'react'

class PickerDemo extends Component{
  constructor(props){
  console.log('01构造函数');
  super(props)
    this.state={
      msg: "我是 msg 数据"
    }
  }
  //组件将要挂载时候触发的生命周期函数
  componentWillMount(){
    console.log('02组件将要挂载')
  }
  //组件挂载完成时候触发的生命周期函数
  componentDidMount(){
    console.log('04组件将要挂载')
  }
  render(){
    console.log('03数据渲染render')
    return(
      <div>
        生命周期函数演示
      </div>
    ) 
  }
}
export default PickerDemo;
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

打开控制台查看

01构造函数
02组件将要挂载
03数据渲染render
04组件将要挂载
1
2
3
4

# 三、数据更新部分

数据更新的话第一步是 shouldComponentUpdate 确认是否要更新数据,当这个函数返回的是 true 的时候才会进行更新,并且这个函数可以声明两个参数 nextPropsnextStatenextProps 是父组件传给子组件的值,nextState 是子组件数据更新之后的值。第二步当确认更新数据之后 componentWillUpdate 将要更新数据,第三步依旧是 render,数据发生改变 render 重新进行了渲染。第四步是 componentDidUpdate 数据更新完成。

React shouldComponent 使用 (opens new window)

# 四、单独说一下componentWillReceiveProps,父组件中改变了props传值时触发的函数

这个函数也就是 props 的值发生改变时(父子组件传值或者通过 connectredux 接收的值)触发的函数,刚才在第二部分中也说到 shouldComponentUpdate 这个函数可以携带两个参数, nextProps 就是父组件传给子组件的值。 在父组件中定义一个初始 msg 数据,写一个按钮声明一个 onClick 事件去改变这个 msg

# 五、componentWillUnmount组件将要销毁时的函数

在父组件中定义一个 flagtrue 的状态值,添加一个按钮声明一个 onClick 事件去 更改这个 flag 实现销毁组件。

这里可以看到 componentWillReceiveProps 这个函数被触发了,nextProps 这个值也发生了改变。

父组件代码:App.js

import React, { Component } from 'react';
import Son from './components/Son'

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      flag: true,
      title: "我是app组件的标题"
    };
  }
  //创建/销毁组件
  setFlag = () => {
    this.setState({
      flag: !this.state.flag
    });
  };
  //改变title
  setTitle = () => {
    this.setState({
      title: "我是app组件改变后的title"
    });
  };
  render() {
    return (
      <div className="App">
        {this.state.flag ? <Son title={this.state.title} /> : ""}
        <hr />
        <button onClick={this.setFlag}>挂载/销毁生命周期函数组件</button>
        <button onClick={this.setTitle}>改变app组件的title</button>
      </div>
    );
  }
}
export default App;
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

子组件代码:Son.js

import React ,{Component} from 'react'

class Son extends Component {
  constructor(props) {
    super(props);
    this.state = {
      msg: "我是一个msg数据"
    };
  }
  //组件将要挂载时候触发的生命周期函数
  componentWillMount() {
    console.log("02组件将要挂载");
  }
  //组件挂载完成时候触发的生命周期函数
  componentDidMount() {
    //Dom操作,请求数据放在这个里面
    console.log("04组件挂载完成");
  }
  //是否要更新数据,如果返回true才会更新数据
  shouldComponentUpdate(nextProps, nextState) {
    console.log("01是否要更新数据");
    console.log(nextProps); //父组件传给子组件的值,这里没有会显示空
    console.log(nextState); //数据更新后的值
    return true; //返回true,确认更新
  }
  //将要更新数据的时候触发的
  componentWillUpdate() {
    console.log("02组件将要更新");
  }
  //更新数据时候触发的生命周期函数
  componentDidUpdate() {
    console.log("04组件更新完成");
  }
  //你在父组件里面改变props传值的时候触发的函数
  componentWillReceiveProps(nextProps) {
    console.log("父子组件传值,父组件里面改变了props的值触发的方法");
  }
  setMsg = () => {
    this.setState({
      msg: "我是改变后的msg数据"
    });
  };

  //组件将要销毁的时候触发的生命周期函数,用在组件销毁的时候执行操作
  componentWillUnmount() {
    console.log("组件销毁了");
  }
  render() {
    console.log("03数据渲染render");
    return (
      <div>
        生命周期函数演示--{this.state.msg}--{this.props.title}
        <br />
        <button onClick={this.setMsg}>更新 msg 数据</button>
      </div>
    );
  }
}
export default Son;
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

点击挂载/销毁生命周期函数组件这个按钮的时候,子组件消失,控制台打印:组件销毁了。

当点击子组件的更新 msg 数据的按钮时,打印结果如下:

01是否要更新数据
{title: '我是app组件改变后的title'}
{msg: '我是改变后的msg数据'}
02组件将要更新
03数据渲染render
04组件更新完成
1
2
3
4
5
6

当点击改变 app 组件的 title 这个按钮时,打印结果如下:

父子组件传值,父组件里面改变了props的值触发的方法
01是否要更新数据
{title: '我是app组件改变后的title'}
{msg: '我是改变后的msg数据'}
02组件将要更新
03数据渲染render
04组件更新完成
1
2
3
4
5
6
7

从打印结果可以看到componentWillReceiveProps这个函数在子组件 props 值更新时被触发了,nextProps拿到的即是最新的 父组件修改的最新的props。

在线运行查看结果 (opens new window)