React框架生命周期总结

简介: React生命周期中各个生命周期方法的特性和使用技巧。

生命周期(Life Cycle):是指一个对象的生老病死。此处的生命周期指的是在对应的框架中一个组件(对象)或程序从创建到销毁的过程。

React生命周期图

react-life-cycle.png

React生命周期详解

React生命周期大体分为四个周期: 初始化、挂载、更新、卸载。

1.初始化期:

  • getDefautProps (es6: static defaultProps)
  • getInitialState (es6: constructor(props))

2.挂载期:

  • componentWillMount
  • render
  • componentDidMount

3.更新期

  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate

4.卸载

  • componentWillUnmount

    示例演示

初始化和挂载期代码演示:

src/index.js

import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <App />,
  document.getElementById('root')
);

src/App.js


class App extends Component {
  static defaultProps = {
    title: (() => {
      console.log(`defaultProps 初始期`)
      return 'app';
    })()
  }

  constructor(props) {
    super(props);
    this.state = {
      name: (() => {
        console.log(`this.state constructor时期`);
        return 'react'
      })()
    }
  }

  componentWillMount() {
    console.log(`componentWillMount 方法`)
  }

  componentDidMount() {
    console.log(`componentDidMount 方法`)
  }

  componentWillReceiveProps() {
    console.log(`componentWillReceiveProps 方法`)
  }

  shouldComponentUpdate() {
    console.log(`shouldComponentUpdate 方法`)
  }

  componentWillUpdate() {
    console.log(`componentWillUpdate 方法`)
  }

  componentDidUpdate() {
    console.log(`componentDidUpdate 方法`)
  }

  componentWillUnmount() {
    console.log(`componentWillUnmount 方法`)
  }

  render() {
    console.log(`render 方法`)
    return <div>{this.props.title} {this.state.name}</div>
  }
}

export default App;

运行结果:

App.js:6 defaultProps 初始期
App.js:15 this.state constructor时期
App.js:22 componentWillMount 方法
App.js:50 render 方法
App.js:26 componentDidMount 方法

更新期代码演示:

更新器分两种情况,一种是自身变化(state),另一种是父组件变化(props)。

自身state变化的情况:

src/App.js


class App extends Component {
  static defaultProps = {
    title: (() => {
      console.log(`defaultProps 初始期`)
      return 'app';
    })()
  }

  constructor(props) {
    super(props);
    this.state = {
      name: (() => {
        console.log(`this.state constructor时期`);
        return 'react'
      })()
    }
  }

  componentWillMount() {
    console.log(`componentWillMount 方法`)
  }

  componentDidMount() {
    console.log(`componentDidMount 方法`)
  }

  componentWillReceiveProps() {
    console.log(`componentWillReceiveProps 方法`)
  }

  shouldComponentUpdate() {
    console.log(`shouldComponentUpdate 方法`)
    return true;
  }

  componentWillUpdate() {
    console.log(`componentWillUpdate 方法`)
  }

  componentDidUpdate() {
    console.log(`componentDidUpdate 方法`)
  }

  componentWillUnmount() {
    console.log(`componentWillUnmount 方法`)
  }

  handleClick() {
    console.log(`点击了【按钮】`);
    this.setState({
      name: 'vue'
    })
  }

  render() {
    console.log(`render 方法`)
    return (
    <div>
      <button onClick={() => this.handleClick()}>按钮</button>
      <br />
      <span>
        {this.props.title} {this.state.name}
      </span>
    </div>
    )
  }
}

export default App;

运行结果:

App.js:6 defaultProps 初始期
App.js:15 this.state constructor时期
App.js:22 componentWillMount 方法
App.js:58 render 方法
App.js:26 componentDidMount 方法
App.js:51 点击了【按钮】
App.js:34 shouldComponentUpdate 方法
App.js:39 componentWillUpdate 方法
App.js:58 render 方法
App.js:43 componentDidUpdate 方法

父组件变化(props)的情况:

src/App.js

import Child from './Child';

class App extends Component {
  static defaultProps = {
    title: (() => {
      console.log(`defaultProps 初始期`)
      return 'app';
    })()
  }

  constructor(props) {
    super(props);
    this.state = {
      name: (() => {
        console.log(`this.state constructor时期`);
        return 'react'
      })()
    }
  }

  componentWillMount() {
    console.log(`componentWillMount 方法`)
  }

  componentDidMount() {
    console.log(`componentDidMount 方法`)
  }

  componentWillReceiveProps() {
    console.log(`componentWillReceiveProps 方法`)
  }

  shouldComponentUpdate() {
    console.log(`shouldComponentUpdate 方法`)
    return true;
  }

  componentWillUpdate() {
    console.log(`componentWillUpdate 方法`)
  }

  componentDidUpdate() {
    console.log(`componentDidUpdate 方法`)
  }

  componentWillUnmount() {
    console.log(`componentWillUnmount 方法`)
  }

  handleClick() {
    console.log(`点击了【按钮】`);
    this.setState({
      name: 'vue'
    })
  }

  render() {
    console.log(`render 方法`)
    return (
    <div>
      <button onClick={() => this.handleClick()}>按钮</button>
      <br />
      <Child title={this.state.name}/>
    </div>
    )
  }
}

export default App;

src/Child.jsx


class Child extends Component {
  
  constructor(props) {
    super(props);
    console.log(`constructor 方法`)
  }

  componentWillMount() {
    console.log(`componentWillMount 方法`)
  }

  componentDidMount() {
    console.log(`componentDidMount 方法`)
  }

  componentWillReceiveProps() {
    console.log(`componentWillReceiveProps 方法`)
  }

  shouldComponentUpdate() {
    console.log(`shouldComponentUpdate 方法`)
    return true;
  }

  componentWillUpdate() {
    console.log(`componentWillUpdate 方法`)
  }

  componentDidUpdate() {
    console.log(`componentDidUpdate 方法`)
  }

  componentWillUnmount() {
    console.log(`componentWillUnmount 方法`)
  }

  render() {
    console.log(`render 方法`)
    return (
    <div>
      {this.props.title}
    </div>
    )
  }
}

export default Child;

运行结果:

App.js:7 defaultProps 初始期
App.js:16 this.state constructor时期
App.js:23 componentWillMount 方法
App.js:59 render 方法
Child.jsx:7 constructor 方法
Child.jsx:11 componentWillMount 方法
Child.jsx:40 render 方法
Child.jsx:15 componentDidMount 方法
App.js:27 componentDidMount 方法
App.js:52 点击了【按钮】
App.js:35 shouldComponentUpdate 方法
App.js:40 componentWillUpdate 方法
App.js:59 render 方法
Child.jsx:19 componentWillReceiveProps 方法
Child.jsx:23 shouldComponentUpdate 方法
Child.jsx:28 componentWillUpdate 方法
Child.jsx:40 render 方法
Child.jsx:32 componentDidUpdate 方法
App.js:44 componentDidUpdate 方法

卸载期演示:

src/App.js

import Child from './Child';

class App extends Component {
  static defaultProps = {
    title: (() => {
      console.log(`defaultProps 初始期`)
      return 'app';
    })()
  }

  constructor(props) {
    super(props);
    this.state = {
      name: (() => {
        console.log(`this.state constructor时期`);
        return 'react'
      })()
    }
  }

  componentWillMount() {
    console.log(`componentWillMount 方法`)
  }

  componentDidMount() {
    console.log(`componentDidMount 方法`)
  }

  componentWillReceiveProps() {
    console.log(`componentWillReceiveProps 方法`)
  }

  shouldComponentUpdate() {
    console.log(`shouldComponentUpdate 方法`)
    return true;
  }

  componentWillUpdate() {
    console.log(`componentWillUpdate 方法`)
  }

  componentDidUpdate() {
    console.log(`componentDidUpdate 方法`)
  }

  componentWillUnmount() {
    console.log(`componentWillUnmount 方法`)
  }

  handleClick() {
    console.log(`点击了【按钮】`);
    this.setState({
      name: 'vue'
    })
  }

  render() {
    console.log(`render 方法`)
    return (
    <div>
      <button onClick={() => this.handleClick()}>按钮</button>
      <br />
      { this.state.name === 'react' ? <Child title={this.state.name}/> : null }
    </div>
    )
  }
}

export default App;

运行结果:

App.js:7 defaultProps 初始期
App.js:16 this.state constructor时期
App.js:23 componentWillMount 方法
App.js:59 render 方法
Child.jsx:7 constructor 方法
Child.jsx:14 componentWillMount 方法
Child.jsx:46 render 方法
Child.jsx:18 componentDidMount 方法
App.js:27 componentDidMount 方法
App.js:52 点击了【按钮】
App.js:35 shouldComponentUpdate 方法
App.js:40 componentWillUpdate 方法
App.js:59 render 方法
Child.jsx:42 componentWillUnmount 方法
App.js:44 componentDidUpdate 方法

各个回调方法的特性

constructor:

constructor函数是在对应组件初始化时调用的构造方法,构造方法就是该组件的出生方法,对应的对象只能出生一次,所以对应的实例组件一生只能调用一次,除非销毁重新生成。该方法的执行时间点是静态资源初始化执行后(static修饰的属性),componentWillMount方法执行前执行。constructor方法带有一个参数是props,参数props是父级中调用该组件时设置的属性集对象。该方法中第一行必须调用 super(props); 因为实现的组件都是继承自React.Compent对象,调用这个方法才能实现父组件props变化时自身渲染结果随之改变。

特性:

• 参数props父级传递下来的props对象
• constructor中必须写super(props)
• 组件初始化的时候调用,整个生命周期中只调用一次
• 在类中的静态资源加载完后执行(static defaultProps就是静态资源)

用途:

该方法的主要用途是用来初始化组件中的属性和定义属性的。所以我们一般都在这个方法中定义state中的属性,或定义一下实例变量。

componentWillMount

componentWillMount() 这个生命周期方法是React的第一个生命周期方法,该方法在组件对象的基础属性及方法都初始化完成后调用,调用这个方法就是说React开始准备接管这个对象了。

特性:

• 在组件挂载到DOM前调用,且只会被调用一次
• 调用this.setState不会引起组件重新渲染(此时还没有挂载到DOM上)

用途:

该方法中主要是初始化一下数据或在组件初始化的时候去请求数据。

componentDidMount

componentDidMount() 这个生命周期方法应该是用的最多的,一般用在进入页面后,数据初始化。componentDidMount与componentWillMount的区别是:componentWillMount是在render方法前调用的,componentDidMount是在render方法后调用的,render方法后对应的该组件就挂载到DOM上了,就可以完全被react接管了,此时可以调用this.setState方法了。

特性:

• 组件挂载到DOM后调用,且只会被调用一次
• 挂载到DOM后调用this.setState就会引起组件重新渲染

用途:

该方法中与componentWillMount用法差不多,但是这个方法中可以调用this.setState,可以重新渲染界面。

componentWillReceiveProps

componentWillReceiveProps(nextProps) 这个生命周期的方法是在组件挂载到DOM后属性变化后调用的。组件中的属性是由父组件中传递过来的值,在这个方法中可以判断父组件中传过来的值和该组件内值是否相等来判断是否指定属性改变了,来处理特定属性的行为。

特性:

• 参数是nextProps改变后的props对象
• 调用 this.setState不会引起第二次渲染,所以可以在此函数中根据props的变化设置state的值
• 当前组件中的this.props还是原来的值,还没有变化

用途:

该方法主要是来监控属性props的变化的,对特殊属性props的变化做出特别处理。可以过滤出对应属性变化来重新渲染组件,防止组件属性改变每次都渲染组件。

shouldComponentUpdate

shouldComponentUpdate(nextProps, nextState) 这个生命周期的方法是在props和state属性变化后都会调用的方法,用来判断是否需要重新渲染。此方法中的返回值用来决定是否重新渲染,返回true表示需要重新渲染,返回false反之。此方法返回true后会调用componentWillUpdate方法。

特性:

• 参数nextProps、nextState 分别表示变化后的props和state
• 当前组件中的this.props和this.state还是原来的值,还没有变化
• 可比较this.props、this.state和nextProps、nextState 中的值是否有变化
• 此函数return一个布尔值,表示是否需要重新渲染DOM

用途:

我们可以通过shouldComponentUpdate生命周期函数来来判断当前组件所在的props、state和context发生改变时,当前组件还是否需要进行更新操作(可以认为为当前组件自定义一个diff算法),以达到性能的最大优化。

componentWillUpdate

componentWillUpdate(nextProps, nextState) 这个生命周期的方法是在shouldComponentUpdate方法后调用,此方法调用后就会去调用render方法重新渲染界面。此方法中的参数是props变化后的值(父组件传递进来的值),该组件中的props还是原来的值还没有改变。

特性:

• 参数nextProps、 nextState 分别表示变化后的props和state
• 当前组件中的this.props和this.state还是原来的值,还没有变化
• 此方法在调用render方法前执行

用途:

DOM重新渲染前调用,用来查看界面最后渲染时值的前后变化。

componentDidUpdate

componentDidUpdate(prevProps, prevState) 这个生命周期的方法是在componentWillUpdate方法后调用过render后再调用。此方法调用后表示一个渲染过程完成。

特性:

• 参数prevProps, prevState 分别表示变化前的props和state
• 当前组件中的this.props和this.state的值已经变化
• 此方法掉用render方法后执行

用途:

DOM重新渲染后调用,可以用了查看渲染后属性值的前后变化。

componentWillUnmount

componentWillUnmount() 这个生命周期的方法是在组件销毁前调用。

特性:

• 此方法在组件被卸载前调用,可以在这里执行一些清理工作

用途:

组件销毁前做一些清理工作。如:clearTimeout, clearInterval

render

render() 方法用来重新渲染界面。

特性:

• 在componentWillMount后,componentDidMount前会被调用一次
• 在componentWillUpdate后,componentDidUpdate前会被调用
• 不能执行this.setState(会死循环)

相关文章
|
1月前
|
前端开发 JavaScript 开发者
颠覆传统:React框架如何引领前端开发的革命性变革
【10月更文挑战第32天】本文以问答形式探讨了React框架的特性和应用。React是一款由Facebook推出的JavaScript库,以其虚拟DOM机制和组件化设计,成为构建高性能单页面应用的理想选择。文章介绍了如何开始一个React项目、组件化思想的体现、性能优化方法、表单处理及路由实现等内容,帮助开发者更好地理解和使用React。
74 9
|
2月前
|
前端开发 JavaScript
React 组件生命周期
React 组件生命周期
30 0
|
20天前
|
存储 前端开发
在React框架中,如何使用对象来管理组件的状态
在React中,组件状态通过`state`对象管理,利用`setState`方法更新状态。状态变化触发组件重新渲染,实现UI动态更新。对象结构清晰,便于复杂状态管理。
|
29天前
|
开发框架 前端开发 JavaScript
React 框架的优点和缺点是什么?
React框架作为当前主流的前端开发框架之一,具有诸多优点,同时也存在一些缺点
|
29天前
|
JavaScript 前端开发 算法
React 框架和 Vue 框架的区别是什么?
React框架和Vue框架都是目前非常流行的前端JavaScript框架,它们在很多方面存在区别
|
29天前
|
移动开发 前端开发 JavaScript
React框架
React是一个用于构建用户界面的JavaScript库,由Facebook开发并于2013年开源,目前在前端开发领域得到了广泛的应用。
|
1月前
|
前端开发 JavaScript
react 组件的生命周期
React组件的生命周期包括从创建到销毁的各个阶段,如挂载(mounting)、更新(updating)和卸载(unmounting)。每个阶段都有特定的方法,用于控制组件的行为和状态,确保高效、有序地渲染和管理UI。
|
2月前
|
缓存 前端开发 JavaScript
前端serverless探索之组件单独部署时,利用rxjs实现业务状态与vue-react-angular等框架的响应式状态映射
本文深入探讨了如何将RxJS与Vue、React、Angular三大前端框架进行集成,通过抽象出辅助方法`useRx`和`pushPipe`,实现跨框架的状态管理。具体介绍了各框架的响应式机制,展示了如何将RxJS的Observable对象转化为框架的响应式数据,并通过示例代码演示了使用方法。此外,还讨论了全局状态源与WebComponent的部署优化,以及一些实践中的改进点。这些方法不仅简化了异步编程,还提升了代码的可读性和可维护性。
|
25天前
|
JavaScript 前端开发 开发者
JavaScript框架React vs. Vue:一场性能与易用性的较量
JavaScript框架React vs. Vue:一场性能与易用性的较量
31 0
|
2月前
|
前端开发 JavaScript UED
构建现代Web应用:使用React框架打造单页面应用
【10月更文挑战第9天】构建现代Web应用:使用React框架打造单页面应用