React(v16.8.4)生命周期详解
当前版本v16.8.4
装载过程(组件第一次在DOM树中渲染的过程):
constructor(常用) -> getInitialState(v16.0已废弃) -> getDefaultProps(v16.0已废弃) -> componentWillMount(v17.0中将被弃用) -> getDerivedStateFromProps(v16.3新增,并在v16.4中升级优化了一下) -> render(必须要) -> componentDidMount(常用)
更新过程(当组件被重新渲染的过程,state改变或props改变或父组件forceUpdate引发子组件的重新渲染):
componentWillReceiveProps(v17.0中将被弃用) -> getDerivedStateFromProps -> shouldComponentUpdate -> componentWillUpdate(v17.0中将被弃用) -> render -> getSnapshotBeforeUpdate -> componentDidUpdate
卸载过程(组件从DOM中删除的过程):
componentWillUnmount
错误处理(当组件发生错误的时候,用得极少)
getDerivedStateFromError(v16.6新增) -> componentDidCatch(未来将被废弃)
constructor:(可以不写,直接写state = {})
ES6中每个类的构造函数,并不是每个组件都需要定义自己的构造函数。比如无状态组件。
作用:
- 初始化state, 例如super(props)下的 this.state = {}
- 绑定成员函数的this环境。例如 this.onClickButton = this.onClickButton.bind(this)。但这种方案一般都会用箭头函数代替
而综合以上两点作用,其实很多时候,你会在antd官网的例子上看到一些例子,并没有使用contructor, 而是直接简写为
state = {
count: 0
}
// 这是因为在ES6的继承中,其实不管子类写不写constructor,在new实例的过程都会给补上constructor
class ColorPoint extends Point {
}
// 等同于
class ColorPoint extends Point {
constructor(...args) {
super(...args);
}
}
getInitialState: (随着v16.0版本createClass被弃用,该方法也不存在了)
返回值会用来初始化组件的this.state
getDefaultProps: (随着v16.0版本createClass被弃用,该方法也不存在了)
返回值可以作为props的初始值
componentWillMount:(即将在v17.0中被弃用,不用)
可以做:
- 直接使用setState改变组件状态,render会打印一次改变后的值(但是你这样做没什么意义,还不如直接在constructor的时候设好初始值)
- 发送Ajax请求(服务端渲染的时候)
不要做:
- 发送ajax请求(原因如下)
- 执行DOM操作(这个阶段DOM还没渲染出来)
最终建议:
不要用这个生命周期
在没被弃用的时候也几乎不用,这时候没有任何渲染出来的结果,即使调用this.setState修改状态也不会引发重新绘制。所有在这里可以做的事,都可以提前到 constructor中去做。有些人可能用过vue, 在vue中也经常在created中去请求接口,比如可能初始值是0,然后在created中请求接口,简单的理解成想页面在展示的时候就直接显示接口请求返回后的数据1了,而不是我们看到页面的时候先看到0,然后突然变成1了。个人理解vue的created和react的componentWillMount应该也是相差不了太多的,如果是在componentWillMount的时候你的数据还不是1的话,你这时候请求数据,其实是另外开了一个线程去执行异步操作了,render函数并不会等你异步请求结果返回1才去执行render。网络差的话,你先看到0再看到突然变成1也是很正常的事。在这里请求和在componentDidMount中请求并不会有太大的差别。同理,其实vue中特意区分该在created中还是mounted中请求接口也是没必要的,还不如统一到mounted/componentDidMount中去请求接口,因为我们有些方法还是要等真实dom存在后才去执行的。
getDerivedStateFromProps(props, state):
第一次在装载阶段(当前组件实例化)会被触发比较好理解,但是组件更新阶段,究竟组件更新阶段的什么操作会触发这个函数?
假如我在父组件改变了props 会触发这个函数吗?答案是会。
假如我在当前组件 this.setState 会触发这个函数吗?在v16.3中不会,但是在v16.4以上就会了。截至2019-03-17,在 https://react.docschina.org/docs/react-component.html#static-getderivedstatefromprops 上看到的翻译还是错的。不信可以自己试试?
假如我在父组件只是执行了 forceUpdate 强行引发一次重新绘制,那当前组件(子组件)的getDerivedStateFromProps又会被触发吗?
一样,在v16.3中不会,但是在v16.4以上就会了。
它返回一个对象来更新状态,如果返回的是null就表示不更新任何内容
这个方法react官方都意识到很多人对如何使用它存在许多误解(https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html),
目前很多人的博客其实写得也有点问题的。
render:(必须要)
返回一个JSX表示的对象,然后由React库来根据返回对象决定如何渲染。并不是返回的真实DOM,其他的生命周期都可以省,但是这个必须要
componentDidMount:(常用)
可以做:
- 发送ajax请求
不要做:
- 直接使用this.setState更新状态,这样会二次渲染(不过经常会有发送请求后,在回调函数里setState,这也是不可避免的)
仅在浏览器端执行,此时已经有了真实的dom节点,在这个阶段常用于处理接口请求,或者一些DOM操作。因为有些组件的启动动作是依赖DOM的,例如动画等。
需要注意的是:可以在这里发送异步请求,在回调函数里调用setState设置state。但是尽量不要在这里直接调用setState()设置状态。因为会触发一次额外的重新渲染,可能造成性能问题。
componentWillReceiveProps(nextProps):(即将在v17.0中被弃用,不用)
可以做:
- 根据props的更新同步组件状态。
不要做:
- 发送ajax请求
- 尤其是不要在这里setState
当前组件setState()不会调用;
父组件props改变会调用;
父组件通过forceUpdate重新执行render,也会调用当前组件的componentWillReceiveProps;
只要父组件的render函数被调用,那么当前组件(子组件)都会触发这个函数,不管父组件的props发不发生变化。例如父组件执行了 forceUpdate 强行引发一次重新绘制。当前组件的componentWillReceiveProps就会被触发。而在当前组件this.setState是不会触发这个函数的。因为componentWillReceiveProps适合根据新的props值(也就是参数nextProps)来计算出是不是要更新内部状态state。更新组件内部状态的方法就是this.setState。如果this.setState的调用导致componentWillReceiveProps再依次被调用,那就是一个死循环了。
componentWillReceiveProps(nextProps) {
if (this.props.oneProp !== nextProps.oneProp) {
// 很多人会在这里同时写setState 并且 发送异步请求,其实这是不合理的
// 应该只在这里根据props的改变去执行 setState来同步props到组件的状态中, 不该在这里发送异步请求
}
}
// 现如今更好的方式是使用getDerivedStateFromProps 去改变state 和 componentDidUpdate 去异步请求 来代替上面的方案
shouldComponentUpdate(nextProps, nextState):(如果你对性能有更极致的要求,水平没达到一定高度就不要去动它了)
当前组件setState()会调用;
父组件props改变会调用;
父组件通过forceUpdate重新执行render,不会调用当前组件的shouldComponentUpdate;
这个方法主要是为了性能优化而设计的,考虑使用内置的PureComponent,而不是自己在这个函数里写比较,更不建议在这个组件里使用JSON.stringify去深度检查,效率非常低。
这里返回一个布尔值,默认都返回的true, 如果返回false,那这个生命周期后面的更新阶段的生命周期都不会执行了。
componentWillUpdate(nextProps, nextState):(即将在v17.0中被弃用,不用)
它可以做的,不要做的同componentWillMount一样
当前组件setState()会调用;
父组件props改变会调用;
父组件通过forceUpdate重新执行render,也会调用当前组件的shouldComponentUpdate;
其实和componentWillMount类似,
这个方法也应该尽量避免使用,将要被遗弃。几乎用不上。应该都统一到componentDidUpdate中去处理。
getSnapshotBeforeUpdate(prevProps, prevState):
setState(),props发生改变,父组件重新render都会调用。发生在更新状态的render之后,这时候已经可以读取dom了。通常用于处理滚动位置的聊天线程等UI中。
和getDerivedStateFromProps一样它返回一个对象来更新状态,如果返回的是null就表示不更新任何内容
componentDidUpdate(prevProps, prevState):
它可以做的,不要做的同componentDidUpdate一样
setState(),props发生改变,父组件重新render都会调用。这个方法相对用得也比较多。同componentDidMount处理事件函数类似,如果组件被更新的时候,原有的内容被重新绘制后可能也需要再次处理事件函数。
componentDidUpdate(prevProps, prevState) {
if(prevProps.oneProp !== this.props.oneProp) {
// 如果有变化,在这里做一些异步请求,可能会在异步请求的回调函数里setState
// 不要直接去执行this.setState
}
}
componentWillUnmount():
当react组件要从dom树上删除掉的时候,这个方法就会被调用。
如果在componentDidMount中使用非React的方法创造了一些DOM元素,如果撒手不管可能会造成内存泄漏,那就需要在componentWillUnmount中把这些创造的DOM元素清理掉。
应用场景:清理定时器,关闭socket, 清除监听器等
import React, { Component } from "react";
export default class LifeCycle extends Component {
state = {
}
static getDerivedStateFromProps(props, state) {
}
componentDidMount = () => {
}
shouldComponentUpdate = (nextProps, nextState) => {
}
getSnapshotBeforeUpdate = (prevProps, prevState) => {
}
componentDidUpdate = (prevProps, prevState) => {
}
componentWillUnmount = () => {
}
render() {
return (
<div>
</div>
)
}
}
React(v16.8.4)生命周期详解的更多相关文章
- React—组件生命周期详解
React—组件生命周期详解 转自 明明的博客 http://blog.csdn.net/slandove/article/details/50748473 (非原创) 版权声明:转载请注明出处,欢 ...
- ASP.NT运行原理和页面生命周期详解及其应用
ASP.NT运行原理和页面生命周期详解及其应用 1. 下面是我画的一张关于asp.net运行原理和页面生命周期的一张详解图.如果你对具体不太了解,请参照博客园其他帖子.在这里我主要讲解它的实际应用. ...
- ASP.NET生命周期详解
最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多处理流程,如管道事件等 ...
- ASP.NET生命周期详解 [转]
最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多处理流程,如管道事件等 ...
- ASP.NET生命周期详解(转)
看到好文章需要分享. 最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多 ...
- React生命周期详解
React生命周期图解: 一.旧版图解: 二.新版图解: 从图中,我们可以清楚知道React的生命周期分为三个部分: 实例化.存在期和销毁时. 旧版生命周期如果要开启async rendering, ...
- react 生命周期详解
state有时候很不听话,在某些时候,我不想他渲染,偏偏react非常智能的帮我们重复渲染. 比如最常见的就是传递的对象为空,组件依旧渲染了一次或者多次. 更多场景不举例了,对症下药. shouldC ...
- 【转】Java 类的生命周期详解
一. 引 言 最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目前国内java方面的教材大 ...
- activity的生命周期详解
刚在看mars老师的视频,看到activity的生命周期,就看了一下,总结了一下.下面是各函数的调用时机 为了更清楚的看清楚工作的具体过程,举例如下: ,建立两个activity,一个main,一个a ...
随机推荐
- [HackerRank]New Year Chaos[UNDONE]
Input (stdin)Download 2 8 5 1 2 3 7 8 6 4 8 1 2 5 3 7 8 6 4 Your Output (stdout) Too chaotic Too cha ...
- 【转】 如何重写hashCode()和equals()方法
转自:http://blog.csdn.net/neosmith/article/details/17068365 hashCode()和equals()方法可以说是Java完全面向对象的一大特色.它 ...
- 导出python的环境
1.导出 pip freeze > packegas.txt 2.在其他环境安装 pip install -r packages.txt
- 连接SQL Server数据库
SqlConnection来连接数据库,注意数据库目标的格式. using System.Data.SqlClient;//载入数据库命名空间 namespace WindowsFormsApplic ...
- iOS开发者知识普及,Swift 挑战 Objective-C,谁会笑到最后?
前言: 目前全球共有超过 7 亿台 iPhone 处于活跃状态,全球约有2000万名 iOS 开发者,这造就了 iOS 作为全球第二大移动设备平台的状态. 虽然安卓系统的全球市场占有率超过 iOS 系 ...
- 单例模式的七种实现-Singleton(Java实现)
1. 饿汉式 实现代码: public class Singleton { private Singleton() { } private static Singleton singleton = n ...
- js检测移动设备并跳转到相关适应页面。
PS:网页自适应的方式有多种.有通过CSS样式表来实现自适应(主流),也有通过显示不同的页面来实现的方式. 下面代码是记录通过判断设备特征来跳转到相关的页面的方法. 实现要求: 当手机,平板访问 a. ...
- ccse(CountDownLatch,CycliBarrier,Semaplore,Exchanger)
关于等待状态的线程调用interrupt方法报异常:InterruptedException 当线程被阻塞,比如wait,join,sleep等,在调用interrupt方法,没有占用cpu运行的线程 ...
- SpringMVC中的数据绑定(也就是参数的接收)
spirngMVC中的数据绑定类型,分为默认数据类型,简单数据类型,pojo类型,包装的pojo类型,绑定数组类型,绑定集合类型,还有自定定义数据绑定. 例如默认数据类型的绑定@RequestMapp ...
- day 18 - 1 正则与 re 模块
正则表达式 官方定义:正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个 “规则字符串”,这个 “规则字符串” 用来表达对字符串的一种过滤逻辑. 我 ...