React躬行记(4)——生命周期

简介:   组件的生命周期(Life Cycle)包含三个阶段:挂载(Mounting)、更新(Updating)和卸载(Unmounting),在每个阶段都会有相应的回调方法(也叫钩子)可供选择,从而能更好的控制组件的行为。

一、挂载


  在这个阶段,组件会完成它的首次渲染,先执行初始化,再被挂载到真实的DOM中,其中依次调用的方法有constructor()、componentWillMount()、render()和componentDidMount()。除了render(),其他三个方法都只会运行一次。

1)constructor()

  在生命周期中,类的构造函数constructor()会率先被执行,用于初始化组件的状态、接收外部传递进来的数据、绑定成员方法的this指向等工作。

2)componentWillMount()

  componentWillMount()方法会运行在render()之前,它是渲染之前的回调函数。不过,由于在这个方法中执行的任务都能提前到constructor()中,因此实际项目中很少会用到它。

3)render()

  render()是在定义组件时必须声明的方法,它是一个无副作用的纯函数,可根据组件的props和state得到一个React元素、null或false等返回值,并且在render()方法中不能调用改变组件状态的this.setState()方法。注意,将元素渲染到页面DOM中的工作都由React负责,而不是render()方法。

4)componentDidMount()

  componentDidMount()方法会运行在render()之后,它是渲染之后的回调函数。此时组件已被挂载到页面中,可以执行DOM相关的操作,例如异步读取服务器中的数据并填充到组件中、调用jQuery代码等。

  下面的组件没有实际用途,仅仅是为了演示四个回调函数,其中componentWillMount()和componentDidMount()都成功调用了this.setState()方法。


class Btn extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: props.name
    };
  }
  componentWillMount() {
    this.setState({age: 28});
  }
  render() {
    return <button>{this.state.name}</button>;
  }
  componentDidMount() {
    $.post("server.php", {id:1}, json => {
      this.setState({age: json.data.age});
    }, "json");
  }
}


二、更新


  引起组件更新(即重新渲染)的方式有三种,第一种是由父组件向下传递props(即调用父组件的render()方法)引起的更新,依次会调用五个方法:componentWillReceiveProps()、shouldComponentUpdate()、componentWillUpdate()、render()和componentDidUpdate()。第二种是通过改变自身state(即调用this.setState()方法)引起的更新,会忽略componentWillReceiveProps()方法,只执行四个回调函数。第三种是通过组件的forceUpdate()方法强制更新,只有后三个回调函数会被执行。在下面的组件中,定义了更新阶段的五个回调函数,并且点击按钮就会触发强制更新。


class Btn extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: "strick"
    };
  }
  dot() {
    this.setState({name: "freedom"});
    this.forceUpdate();            //强制更新
  }
  componentWillReceiveProps(nextProps) { }
  shouldComponentUpdate(nextProps, nextState) { return true; }
  componentWillUpdate(nextProps, nextState) { }
  render() {
    return <button onClick={this.dot.bind(this)}>{this.state.name}</button>;
  }
  componentDidUpdate(prevProps, prevState) { }
}


1)componentWillReceiveProps()

  componentWillReceiveProps()方法常用于执行props更新后的逻辑,只有第一种更新方式才会调用它,该方法能接收一个名为nextProps的参数,表示父组件传递进来的新的props。当需要通过this.setState()方法将nextProps中的数据同步到内部状态时,要先比较nextProps和this.props中的值是否相同,再决定是否执行同步。由于在componentWillReceiveProps()中能调用this.setState()方法,因此为了避免进入一个死循环,在调用this.setState()方法更新组件时就不会触发它。

2)shouldComponentUpdate()

  shouldComponentUpdate()用于决定是否继续组件的更新,它能接收2个参数:nextProps和nextState,分别表示新的props和state,通过比较nextProps、nextState和组件当前的this.props、this.state能得出一个布尔类型的返回结果。当返回结果为false时,组件会停止更新,后续的componentWillUpdate()、render()和componentDidUpdate()也不会被执行。将这个方法使用恰当的话,能减少冗余的渲染,优化组件的性能。

3)componentWillUpdate()和componentDidUpdate()

  componentWillUpdate()和componentDidUpdate()分别运行在render()之前和之后,它们都能接收2个参数,前者提供更新后的props和state,后者提供更新前的props和state。在componentWillUpdate()中,不能调用this.setState()方法,以免发生不必要的死循环。


三、卸载


  当组件在从DOM中被卸载之前,会触发一个无参数的componentWillUnmount()方法。在该方法内适合做些清理的工作,例如清除定时器、移除多余的DOM元素等。下面演示了处理卸载的过程,限于篇幅省略了组件的构造函数和render()方法,只给出了关键代码。

class Btn extends React.Component {
  componentWillUnmount() {
    clearInterval(timeout);
  }
}
var container = document.getElementById("container");
ReactDOM.render(<Btn>提交</Btn>, container);
ReactDOM.unmountComponentAtNode(container);            //移除DOM中的组件



四、流程图


  接下来用一张总的流程图(如图5所示)来说明生命周期各个方法之间的关系,灰底的方法表示在其内部能调用this.setState()方法。


2.png


图5  组件生命周期流程图


五、过时和新增的回调方法


1)过时

  从React v16.3开始,有3个生命周期方法被标记为过时:componentWillMount()、componentWillReceiveProps()和componentWillUpdate(),目前它们仍然有效,但不建议在新代码中使用,官方为它们新增了一个以“UNSAFE_”作为前缀的别名。

2)新增

  React v16新增了两个生命周期方法,如下所列。

  (1)static getDerivedStateFromProps(nextProps, prevState)

  静态方法getDerivedStateFromProps()用来替代componentWillReceiveProps()。它在render()方法之前触发,包含两个参数:nextProps和prevState,分别表示新的props和旧的state。如果返回一个对象,那么更新state;如果返回null,那么就不更新state。

  (2)getSnapshotBeforeUpdate(prevProps, prevState)

  getSnapshotBeforeUpdate()方法用来替代componentWillUpdate()。它在最近一次渲染输出(即更新DOM)之前触发,包含两个参数:prevProps和prevState,分别表示旧的props和旧的state,返回值会成为componentDidUpdate()的第三个参数。

 


相关文章
|
2月前
|
前端开发 JavaScript
React 组件生命周期
React 组件生命周期
34 0
|
1月前
|
前端开发 JavaScript
react 组件的生命周期
React组件的生命周期包括从创建到销毁的各个阶段,如挂载(mounting)、更新(updating)和卸载(unmounting)。每个阶段都有特定的方法,用于控制组件的行为和状态,确保高效、有序地渲染和管理UI。
|
3月前
|
前端开发 JavaScript 开发者
介绍一下React生命周期
介绍一下React生命周期
113 9
|
2月前
|
存储 前端开发 JavaScript
深入理解React组件的生命周期与Hooks
【10月更文挑战第7天】深入理解React组件的生命周期与Hooks
145 0
|
4月前
|
前端开发 JavaScript
React的生命周期演示-新(12)
【8月更文挑战第15天】React的生命周期演示-新
54 5
React的生命周期演示-新(12)
|
4月前
|
前端开发 JavaScript
React的生命周期简介(十)
【8月更文挑战第15天】React的生命周期简介
51 2
|
4月前
|
前端开发 JavaScript
React 组件的生命周期阶段详解
【8月更文挑战第30天】
55 7
|
3月前
|
前端开发 API UED
React组件生命周期详解
【9月更文挑战第4天】在React应用开发中,掌握组件生命周期对于管理状态和属性至关重要,并能有效提升应用性能。本文详细介绍了React组件生命周期的三个阶段:挂载、更新和卸载,并通过代码示例展示了如何避免状态更新导致的死循环及优化网络请求等问题,帮助开发者构建更高效、可维护的应用。
95 2
|
4月前
|
前端开发 JavaScript
React 组件生命周期方法详解
【8月更文挑战第30天】
61 5
|
4月前
|
前端开发 JavaScript
React的生命周期演示-旧(11)
【8月更文挑战第15天】React的生命周期演示-旧(11)
35 3