React组件生命周期

React组件生命周期

React的组件的生命周期分为三个过程:

  1. 装载过程(Mount):第一次把组件渲染到DOM树的过程;
  2. 更新过程(Update):组件进行渲染更新的过程;
  3. 卸载过程(Unmount):组件从DOM树种删除的过程。

装载过程

装载过程主要进行如下操作:

  1. constructor:构造函数,经常是为了初始化state或者绑定成员函数的this环境(建议直接使用箭头函数,则需要在构造函数中进行函数的bind操作);
  2. componentWillMount:预装载函数,不能进行修改state的操作,即使做了,也不会进行新数据状态的渲染。在该函数中做的操作,都可以提前到构造函数中,比较鸡肋。
  3. render:渲染函数,唯一的一定不能省略的函数,必须有返回值,返回null或false表示不渲染任何DOM元素。它是一个仅仅用于渲染的纯函数,返回值完全取决于this.state和this.props,不能在函数中任何修改props、state、拉取数据等具有副作用的操作。render函数返回的是JSX的对象,该函数并不因为这渲染到DOM树,何时进行真正的渲染是有React库决定的。
  4. componentDidMount:挂载成功函数。该函数不会再render函数调用完成之后立即调用,因为render函数仅仅是返回了JSX的对象,并没有立即挂载到DOM树上,而componentDidMount是在组件被渲染到DOM树之后被调用的。另外,componentDidMount函数在进行服务器端渲染时不会被调用。

在React 中,除了render函数之外,都有默认的函数实现,如果不要使用相应的生命周期函数则可以省略。constructor通常用于state的初始化操作,this.state = {};函数绑定this建议在定义的时候直接使用箭头函数来实现,就不需要在constructor函数中进行this绑定操作了。componentWillMount用的很少,比较鸡肋。render函数必须实现,可以通过返回null来进行不渲染。componentDidMount通常用于服务器数据的拉取操作,之所以在componentDidMount中而不是在构造函数中进行数据拉取的原因在于:如果数据拉取回来了,即props已经有值了,但是组件还没有渲染出来,会报错。但是这里有一些把数据拉取提前到constructor函数的思路:在contructor函数中,通过promise来进行数据的拉取,并且绑定到this对象上,然后在componentDidMount中执行promise把数据更新到props上。

更新过程

当组件挂载到DOM树上之后,props/state被修改会导致组件进行更新操作。更新过程会以此调用如下的生命周期函数:

  1. componentWillReceiveProps(nextProps):该函数在组件进行更新以及父组件render函数(不管数据是否发生了改变)被调用后执行,this.props取得当前的props,nextProps传入的是要更新的props。
  2. shouldComponentUpdate(nextProps, nextState):返回bool值,true表示要更新,false表示不更新,使用得当将大大提高React组件的性能,避免不需要的渲染。
  3. componentWillUpdate:预更新函数。
  4. render:渲染函数。
  5. componentDidUpdate:更新完成函数。

相比装载过程的生命周期函数,更新过程的生命周期函数使用的相对来说要少一些。常用的是componentWillReceiveProps、componentShouldUpdate,前者经常用于根据前后两个数据去设置组件的状态,而后者则是常用于优化,避免不必要的渲染。

卸载过程

卸载过程只涉及一个函数componentWillUnmount,当React组件要从DOM树上删除前,会调用一次这个函数。这个函数经常用于去除componentDidMount函数带来的副作用,例如清楚计时器、删除componentDidMount中创造的非React元素。

setState

要修改state,只能使用this.setState(),不能使用this.state.value=2类似方式设置state,一是不会驱动重新渲染,二是很可能被后面的操作替换,造成无法预知的错误。此外,React利用状态队列来实现setState的异步更新,避免频繁地重复更新state。

setState的调用是有风险的,在某些生命周期函数中调用可能会无用甚至早恒循环调用导致崩溃。state的初始化一般在构造函数中实现;setState可以在装载过程的componentWillMount、componentDidMount中调用;setState可以在更新过程中的componentWillReceiveProps、componentDidUpdate中调用。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏三流程序员的挣扎

Flutter 学习记2 - 首个应用

void main() 是入口方法,=> 用于单行方法,就是函数签名和函数体间的连接符号,感觉作用和 Kotlin 的单行函数体用 = 类似。既然这样,把代码修...

851
来自专栏我的博客

Jquery学习第一天

1、jQuery优点 轻量级,强大的选择器,出色的DOM操作,可靠的事件处理,完善的Ajax,不污染的顶级变量,出色的浏览器兼容,链式操作,隐式迭代,行为层和结...

3438
来自专栏阿杜的世界

Spring的容器内部事件发布自定义事件机制Spring 的容器内事件发布类结构应用场景

EventListener接口的作用仅仅在于“标记”,具体要提供哪些功能需要开发者自己定义,而且,还需要为自己定义的接口提供一个默认的实现类——只有接口的话什么...

582
来自专栏更流畅、简洁的软件开发方式

分页控件和几个相关控件的源代码

分页控件的源代码,可能会让有些人失望,因为代码很乱。乱的一个原因呢,可能是没有采用OO的思路吧,因为写控件的时候还一点都不会OO呢,只是一直在用,也就没有作大的...

1955
来自专栏Android Note

Android 资源文件

1304
来自专栏刘望舒

React Native组件(一)组件的生命周期

前言 React Native有很多组件比如Image、ListView等等,想要合理的使用组件,首先要先了解组件的生命周期。 1.概述 无论你是开发Andr...

1745
来自专栏拂晓风起

cocos2d-js 自定义事件监听派发

1003
来自专栏我杨某人的青春满是悔恨

谈谈Swift的extension

3.times { puts 'hello world' } 这是一条Ruby语句,它会打印“hello world”三次,意图清晰,语法简洁。

662
来自专栏salesforce零基础学习

salesforce lightning零基础学习(二) lightning 知识简单介绍----lightning事件驱动模型

看此篇博客前或者后,看一下trailhead可以加深印象以及理解的更好:https://trailhead.salesforce.com/modules/lex...

800
来自专栏静默虚空的博客

React基础篇 - 02.JSX 简介

JSX 简介 请观察下面的变量声明: const element = <h1>Hello, world!</h1>; 这种看起来可能有些奇怪的标签语法既不是字符...

1795

扫码关注云+社区