React生命周期

react 生命周期

生命周期图

生命周期经历三个过程

  • 装载过程(mount), 也就是把组件第一次在DOM树中渲染的过程
  • 更新过程(updata), 当组件被重新渲染的过程
  • 卸载过程(Unmount), 组件充DOM中删除的过程

三种不同的过程,React库会一次调用组件的一些成员函数,即生命周期钩子

装载过程中的生命周期钩子

constructor
getinitialState
getDefaultProps
componentWillMount
render
componentDidMount

getinitialState、getDefaultPropsReact.createClass创建组件时用到的生命周期函数,在高版本的React中已经放弃这种方法,所以这次就不进行展示;

constructor

在面向对象编程中,类(class)是对象(object)的模板,定义了同一组对象(又称"实例")共有的属性和方法。

Javascript语言不支持"类",但是可以用一些变通的方法,模拟出"类"。

阮一峰---js类

阮一峰---ES6 > Class

constructor ES6中每个类的构造函数,并不是每个组件都需要定义自己的构造函数,无状态的React组件往往不需要定义构造函数,一个React组件需要构造函数,往往是为了下面的目的

  • 初始化state,因为组件生命周期中任何函数都可以访问state,那么整个生命周期中第一个被调用构造函数自然是初始化state最理想的地方
  • 绑定成员函数的this

在ES6语法下,类的每个成员函数在执行时this应不是和类实例自动绑定的,而是在构造函数中,this就是当前组件实例,所以为了方便将来的调用,往往在构造函数中将这个实例的特定函数绑定this为当前实例

    this.count = this.count.bind(this)

render

render 函数无疑是React组件中最重要的函数,一个React组件可以忽略其他所有函数都不实现,但是一定要实现render函数,因为React组件的父类React.Component类对除了render之外的生命周期都有默认实现

render 函数并不做实际的渲染动作,它返回一个JSX的描述的结构,最容由React来操作渲染过程

某些特殊组件的作用不是渲染洁面,或者,组件在某些情况下没有什么内容取进行更新,那么让render函数返回一个null或者false,等于告诉React,这次组件不需要渲染任何DOM元素

注意: render 函数应是一个纯函数,完全根据this.statethis.props 来决定返回的结果,而且不要产生任何副作用。在render函数中取调用this.setState毫无疑问是错误的,因为一个纯函数不应该引起状态的改变

componentWillMoun和componentDidMount

在装载过程中,componentWillMount会在调用render函数前被调用,componentDidMount则会在调用render函数后被调用,正好分别来做render前后必备的工作;

componentWillMount 放生在"将要装载"的时候;这个时候没有任何渲染出来的结果,即使调用this.setState修改状态也不会引发重新绘制,因为一切都晚了,在这个时候可以做的事情都可以放到constructor中,可以认为这个函数存在的主要目的是和componentDidMount对称;

componentDidMount 调用在render函数被调用完之后,componentDidMount被调用的时候,render函数返回的东西已经引发了渲染,组件已经被"装载"到DOM树上;值得注意的时,render函数被调用后,componentDidMount函数并不是马上被渲染;

代码如下:
import React, { Component } from 'react';
import Counter from './Counter';  
// app.js
class App extends React.Component {
  render() {
    console.log('enter ControlPanel render')
    return (
      
) } } // Counter.js import React, { Component } from 'react'; class Counter extends Component { constructor(props) { super(props); this.state = { count: this.props.initValue, name: this.props.caption } } componentWillMount () { console.log('render 运行前': this.state.name) } componentDidMount () { console.log('render 运行后': this.state.count) } render () { retrun (
{this.state.name}: {this.state.count}
) } }

结果:

componentDidMount 并不会直接运行

可以清除的看到,componentDidMount是当三个组件都调用完成后,才一起被调用;
因为render函数本身并不往DOM树上渲染或者装载内容,它返回的是一个JSX表示的对象,然后由React库根据返回对象决定如何渲染,而React库把所有组件返回的结果综合起来,才知道如何产生对应的DOM修改,所以React库调用Counter三个组件的render函数后,才有可能完成状态,这个时候才会依次调用组件的componentDIdMount函数;

更新过程

componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate

componentWillReceiveProps

只要父组件的render函数被调用,在render函数里面被渲染的子组件就会经历更新过程,不管父组件传给子组件的props有没有改变,都会触发子组件的componentWillReceiveProps函数。

// 代码 接上部分代码
// app.js

// Counter.js
 componentWillReceiveProps (nextProps) {
    console.log('enter componentReceiveProps' + this.props.name)
 }
父组件render被调用

shouldComponentUpdate(nextProps, nextState)

除了render函数外,shouldCompoentUpdate可能是整个组件生命周期中最重要的一个函数了;

shouldCompoentUpdate函数决定了一个组件什么时候不需要进行渲染;

shouldCompoentUpdaterender是React生命周期函数中唯二两个要求有返回结果的函数,render返回结果将用于构造DOM对象,而shouldCompoentUpdate函数返回一个布尔值,告诉React库这个组件在本次更新中国呢是否继续;

在React库首先调用shouldCompoentUpdate 函数,如果返回true则仅需更新,调用render,如果返回false则停止更新过程,也不会引发后续渲染。

// 代码接上面
// Counter.js
shouldComponentUpdate(nextProps, nextState) {
        return (nextProps.count !== this.props.count) || (nextState.count !== this.state.count)
}
componentWillUpdate () {
    console.log('componentWillUpdate')
}
componentDidUpdate () {
    console.log('componentDidUpdate')
}

当点击aaaa进行刷新时,不会调用shouldComponentUpdate,同时也不会进行componentWillUpdate函数等的调用,当进行加减操作石,则触发;

componentWillUpdate和componentDidUpdate

componentWillUpdate 组件初始化时不调用,只有在组件将要更新时才调用,此时可以修改state

componentDidUpdate 组件初始化时不调用,组件更新完成后调用,此时可以获取dom节点。

卸载过程

componentWillUnmount

防止内存泄漏
用法官方实例

你可能感兴趣的:(React生命周期)