react16 移除的生命周期

componentWillMount

componentWillReceiveProps

componentWillUpdate

react16 新的生命周期

getDerivedStateFromProps

getSnapshotBeforeUpdate

整体生命周期流程图:
react16
完整的生命周期流程(按顺序):

组件进入挂载阶段(Mounting):

constructor

组件的构造函数可以在这里进行 state 初始化
test.js
  • js
1
2
3
4
5
6
7
8
9
class ExampleComponent extends Component {
constructor(props){
super(props);
this.state = {
isLoading: false,
goods: []
}
}
}
getDerivedStateFromProps
test.js
1
static getDerivedStateFromProps(nextProps, prevState)
构造函数初始化后进入该生命周期,取代原先的 componentWillReceiveProps

  • 不能在该函数中使用 this
  • 接收新的props,然后决定是否更新 旧的 state
  • 函数会返回一个对象用来更新当前的state状态,如果不需要可以返回 null

调用时机:

  • 组件挂载时
  • 接收到新的 props 时
  • 调用了setState和forceUpdate时
test.js
  • js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class ExampleComponent extends Component {
constructor(props){
super(props);
this.state = {
isLoading: true,
goods: []
}
}
static getDerivedStateFromProps(nextProps, prevState){
if(nextProps.goods !== prevState.goods){
return {
isLoading: false,
goods: nextProps.goods
}
}
return null
}
}
render

render 方法 返回组件要渲染的东西

componentDidMount

组件装载后调用,可以在这里请求数据,操作DOM 节点。

更新阶段(Update)

更新阶段生命周期函数调用:
  • getDerivedStateFromProps
  • shouldComponentUpdate
  • render
  • getSnapshotBeforeUpdate
  • componentDidUpdate
  • getDerivedStateFromProps

    当组件的props改变,或者组件内部调用了 setState 或者 forceUpdate 会发生

    shouldComponentUpdate

    shouldComponentUpdate(nextProps, nextState)

    在组件 触发 render 之前都会调用这个函数 返回一个布尔值,如果返回 true 组件触发 render 渲染,返回 false 组件不触发 render 函数,默认返回true,所以我们需要在函数中 比较 this.propsnextProps 以及 this.statenextState 来决定是否需要 触发 render 函数渲染

    test.js
    • js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    class ExampleComponent extends Component {
    constructor(props){
    super(props);
    this.state = {
    isLoading: true,
    goods: []
    }
    }
    shouldComponentUpdate(nextProps, nextState){
    if(this.goods.length !== nextState.goods.length){
    return true
    }
    return false
    }
    }

    官方推荐的是组件继承 PureComponent 来减少组件重复渲染的次数,而不是开发者自己手工书写。PureComponent 是官方提供的,在内部对 props 和 state 进行了 一层浅比较

    test.js
    • js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class ExampleComponent extends PureComponent {
    constructor(props){
    super(props);
    this.state = {
    isLoading: true,
    goods: []
    }
    }
    }

    render

    根据 shouldComponentUpdate 返回的值 是否觉得需要调用 render 渲染

    getSnapshotBeforeUpdate

    getSnapshotBeforeUpdate(prevProps, prevState) 这个方法在render之后,componentDidUpdate之前调用,有两个参数prevProps和prevState,表示之前的属性和之前的state,这个函数有一个返回值,会作为第三个参数传给componentDidUpdate,如果你不想要返回值,请返回null,不写的话控制台会有警告 还有这个方法一定要和componentDidUpdate一起使用,否则控制台也会有警告
    test.js
    • js
    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
    class ExampleComponent extends PureComponent {
    constructor(props){
    super(props);
    this.state = {
    messages: []
    }
    }
    componentDidMount(){
    for(let i = 0; i < 20; i++){
    this.handleMessage();
    }
    this.interval = window.setInterval(() => {
    if(this.state.messages.length > 200){
    window.clearInterval(this.interval);
    return;
    }
    this.handleMessage();
    }, 1000);
    }
    getSnapshotBeforeUpdate(prevProps, prevState){
    return this.rootNode.scrollHeight;
    }
    componentDidUpdate(prevProps, prevState, snapshot){
    const scrollTop = this.rootNode.scrollTop;
    if(scrollTop < 5 ) return;
    this.rootNode.scrollTop = scrollTop + (this.rootNode.scrollHeight - snapshot);
    }
    componentWillUnMount(){
    windows.clearInterval(this.interval);
    }
    handleMessage(){
    this.setState( prev => ({
    message: [
    `msg ${prev.messages.length}`,
    ...prev.messages
    ]
    }));
    }
    render(){
    return(
    <div ref={ n => (this.listRef = n) }>
    {this.state.message.map( (msg, idx) => <div key={idx}>{msg}</div>)}
    </div>
    )
    }
    }

    componentDidUpdate

    componentDidUpdate(prevProps, prevState, snapshot)

    该方法在getSnapshotBeforeUpdate方法之后被调用,有三个参数prevProps,prevState,snapshot,表示之前的props,之前的state,和snapshot。第三个参数是getSnapshotBeforeUpdate返回的
    在这个函数里我们可以操作DOM,和发起服务器请求,还可以setState,但是注意一定要用if语句控制,否则会导致无限循环

    卸载阶段(UnMount)

    组件卸载的时候只有一个生命周期函数

    componentWillUnmount

    当我们的组件被卸载或者销毁了就会调用,我们可以在这个函数里去清除一些定时器,取消网络请求,清理无效的DOM元素等垃圾清理工作

    注意不要在这个函数里去调用setState,因为组件不会重新渲染了