资讯专栏INFORMATION COLUMN

2、React组件的生命周期

Jensen / 297人阅读

摘要:组件生命周期严格定义了组件的生命周期,生命周期可能会经历如下三个过程装载过程也就是把组件第一次在树上渲染的过程更新过程当组件被从新渲染的过程卸载过程组件从树中删除的过程。三种不同的过程,库会调用组件的一些成员函数,即生命周期函数。

3. 组件生命周期

React严格定义了组件的生命周期,生命周期可能会经历如下三个过程:

装载过程(Mount):也就是把组件第一次在DOM树上渲染的过程;

更新过程(Updata):当组件被从新渲染的过程;

卸载过程(Unmount):组件从DOM树中删除的过程。

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

3.1、装载过程

当组件第一次被渲染时,依次调用的函数:

static propTypes(createClass创建的话:propTypes)

static defaultProps(createClass创建的话:getDefaultProps(){})

constructor(初始化state;createClass创建的话:getInitalState)

componentWillMount

render

componentDidMount

constructor

ES6中每个类的构造函数,要创建一个组件类的实例,便会调用对应的构造函数
注意:

并不是每个组件都需要定义自己的构造函数,无状态的React组件往往就不需要定义构造
函数;

一个React组件需要构造函数目的:

初始化state,因为组件的生命周期中任何函数都可能要访问state,那么整个周期中第一个被调用的构造函数便是初始化state最理想的地方;

绑定成员函数的this环境:

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

   ...
   constructor(props){
      super(props);
      
      this.onClickFunc = this.onClickFunc.bind(this);
   }

getInitialState和getDefaultProps
  1. getInitialState函数的返回值用来初始化组件的this.state;
  2. getInitialState只出现在装载过程,也就是说一个组件的整个生命周期过程中,这个函数只被调用一次;
  3. getDefaultProps函数的返回值可以作为props的初始值;
  4. 两个函数都只有在使用React.createClass方法创建组件类时才会用到

 const Sample = React.createClass({
   getInitialState: function() {
       return {foo: "返回值将作为this.state的初始值"};
   },
   getDefaultProps: function() {
       return {sampleProp: "作为props的初始值"}
   }
 })

 5. React.createClass创建方法已经逐渐被Facebook官方废弃
  6. 使用ES6时,在构造函数中通过this.state赋值完成状态初始化;通过给类属性(注意是类属性,而不是类的实例对象的属性)defaultProps赋值指定的props初始值:

class Sample extends React.Component{
  constructor (props){
    super(props);
       this.state = {foo: "初始值"}
  }
}
   Sample.defaultProps = {
  sampleProps: 0
}

render

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

通常一个组件要发挥作用,总是要渲染一些东西,render函数并不做实际的渲染动作,它只是返回一个JSX描述结构,最终由React来操作渲染过程;

当某个特殊的组件作用不是渲染界面,或者没有东西可画时,可让render函数返回null或者false,即告诉React此组件不渲染任何DOM元素;

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

componentWillMount和componentDidMount

在装载过程中,componentWillMount会在render函数之前调用,此时还没有任何东西渲染出来,即使调用this.setState修改状态也不会发生重新绘制;

componentDidMount在render函数之后调用,但render调用之后并不会立即调用,而是在render函数返回的东西已经引发了渲染,组件已经被‘装载’到了DOM树上后,componentDidMount才被调用,此时已绘制出真实的DOM树;

注意:

render函数本身并不往DOM树上渲染或者装载内容,它只是返回一个表示JSX表示的对象(及组件实例),然后由React库根据返回的对象决定如何渲染;

而React库肯定是要把所有组件返回的结果综合起来,才能知道如何产生对应的DOM修改;

所以只有React库调用所有组件的render函数之后,才有可能完成DOM装载,这时候才会依调用componentDidMount函数作为装载的收尾。

componentWillMount可以在服务器和浏览器端被调用,而componentDidMount只能在浏览器端被调用(因为componentDidMount是在‘装载’完成之后被调用,且‘装载’是一个创建组件并放到DOM树上的过程,而服务器端渲染通过React组件产生的只是一个纯粹的字符串,并不会产生DOM树,即在服务器端不可能完成‘装载过程’所以无法调用componentDidMount)

3.2、更新过程

随着用户的操作改变展示的内容,当props或者state被修改时,就会引发组件的更新过程;

更新过程会依次调用以下生命周期函数,其中render函数和“装载”过程一样:
 - componentWillReceiveProps
 - shouldComponentUpdate

componentWillUpdate

render

componentDidUpdate

并不是所有的更新过程都会执行全部函数。

componentWillReceiveProps(nextProps)

并不是只有在组件的props发生改变的时候才会调用此函数;

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

注意:通过this.setState方法触发的更新过程不会调用这个函数;

因为,这个函数适合根据新的props值(也就是参数nextProps)来计算是不是要更新内部状态state;而更新内部状态的方法是this.setState,如果this.setState的调用导致componentWillReceiveProps再调用,那将是一个死循环。

shouldComponentUpdate(nextProps,nextState)

除了render函数,shouleComponentUpdate可能是生命周期函数中最重要的一个函数;

因为render函数决定了该渲染什么,shouldComponentUpdate决定了一个组件什么时候不需要渲染;

render和shouldComponentUpdate也是React生命周期函数中唯二两个要求有返回结果的函数;

render函数的返回结果用于构建DOM对象,shouldComponentUpdate函数返回一个布尔值,告诉React库这个组件这次更新过程是否继续;

在更新过程中,React库首先调用shouldComponentUpdate函数,如果这个函数返回true,那就继续更新过程,接下来调用render,反之则终止此次更新过程;

shouldComponentUpdate的参数就是接下来的props和state值;我们可以根据这两个参数,外加this.props和this.state来判断返回true或false,从而避免不必要的更新。

componentWillUpdate和componentDidUpdate

如果组件的shouldComponentUpdate返回true,React接下来调用componentWillUpdate、render和componentDidUpdate;

和“装载”过程不同,这对函数都可以在服务器和浏览器更新阶段调用

不过,通常在使用React做服务端渲染时,基本不会经历更新过程,因为服务器端只需要产出HTML字符串,而一个装载过程就足够产出HTML字符串了,所以正常情况下,服务器端不会调用componentDidUpdate函数,如果调用了,说明程序有错,需要改进。

3.2、卸载过程

React组件的卸载过程只涉及一个函数componentWillUnmount,

当React组件要从DOM树上删除之前,对应的componentWillUnmount函数会被调用,所以这个函数适合做一些清理性的工作。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/93116.html

相关文章

  • 捋一捋React生命周期

    摘要:卸载阶段组件卸载和销毁老版生命周期之前的生命周期初始化阶段涉及个钩子函数这些方法会在组件初始化的时候被调用,只跟实例的创建有关。 前言:React 的版本从 v15 到 v16.3 ,再到v16.4,现在最新的版本是 v16.8了。其中最大的变化可能是React Hooks的加入,而最令人困惑的却是它的生命周期,新旧生命周期函数混杂在一起,难免会让许多新来者有很多困惑。所以这一篇我们来...

    MobService 评论0 收藏0
  • React系列---React(三)组件生命周期

    摘要:组件装载过程装载过程依次调用的生命周期函数中每个类的构造函数,创造一个组件实例,当然会调用对应的构造函数。组件需要构造函数,是为了以下目的初始化,因为生命周期中任何函数都有可能访问,构造函数是初始化的理想场所绑定成员函数的环境。 React系列---React(一)初识ReactReact系列---React(二)组件的prop和stateReact系列---之React(三)组件的生...

    geekzhou 评论0 收藏0
  • Hooks 与 React 生命周期关系

    摘要:更新阶段卸载阶段兄弟节点之间的通信主要是经过父组件和也是通过改变父组件传递下来的实现的,满足的设计遵循单向数据流模型,因此任何两个组件之间的通信,本质上都可以归结为父子组件更新的情况。 你真的了解 React 生命周期吗? React 生命周期很多人都了解,但通常我们所了解的都是 单个组件 的生命周期,但针对 Hooks 组件、多个关联组件(父子组件和兄弟组件) 的生命周期又是怎么样的...

    oliverhuang 评论0 收藏0
  • 不了解一下React16.3之后生命周期

    摘要:本文主要介绍之后的生命周期。该方法有两个参数和返回值为对象不需要返回整体,把需要改变的返回即可。必须有一个返回值,返回的数据类型可以有。此生命周期主要用于优化性能。最后,说明一点这三个生命周期在未来版本中会被废弃。 React16.3.0开始,生命周期进行了一些变化。本文主要介绍React16.3.0之后的生命周期。 React16.3.0之前生命周期: 16版本之前的react组件的...

    468122151 评论0 收藏0
  • React.js 小书 Lesson20 - 更新阶段组件生命周期

    摘要:所以对于组件更新阶段的组件生命周期,我们简单提及并且提供一些资料给大家。这里为了知识的完整,补充关于更新阶段的组件生命周期你可以通过这个方法控制组件是否重新渲染。大家对这更新阶段的生命周期比较感兴趣的话可以查看官网文档。 React.js 小书 Lesson20 - 更新阶段的组件生命周期 本文作者:胡子大哈本文原文:http://huziketang.com/books/react...

    Yumenokanata 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<