react之组件生命周期
四个阶段
- 初始化
- 运行中
- 销毁
- 错误处理(16.3以后)
- 初始化
- constructor
- static getDerivedStateFromProps()
- componentWillMount() / UNSAFE_componentWillMount()
- render()
- componentDidMount()
- 更新
props或state的改变可能会引起组件的更新,组件重新渲染的过程中会调用以下方法:- componentWillReceiveProps() / UNSAFE_componentWillReceiveProps()
- static getDerivedStateFromProps()
- shouldComponentUpdate()
- componentWillUpdate() / UNSAFE_componentWillUpdate()
- render()
- getSnapshotBeforeUpdate()
- componentDidUpdate()
- 销毁
- componentWillUnmount()
- 错误处理
- componentDidCatch()
各个生命周期详解
(1)constructor
- React组件的构造函数在挂在之前被调用。
- 调用
super(props),用来将父组件传来的props绑定到这个类中,使用this.props将会得到。 constructor中应当做些初始化的动作,如:初始化state,将事件处理函数绑定到类实例上,但也不要使用setState()。
使用场景:- 初始化state数据
- 定义函数修改this指向
constructor(props) {
super(props);
this.state = {
isLiked: props.isLiked
};
this.handleFun=this.handleFun.bind(this)
}
(2)static getDerivedStateFromProps(nextProps, prevState)
React 16.3 的版本中 getDerivedStateFromProps 的触发范围是和 16.4^ 是不同的,主要区别是在 setState 和 forceUpdate 时会不会触发,具体可以看这个生命全周期图 。
使用场景:
- 无条件的根据 prop 来更新内部 state,也就是只要有传入 prop 值, 就更新 state
- 只有 prop 值和 state 值不同时才更新 state 值。
Class ColorPicker extends React.Component {
state = {
color: '#000000'
}
static getDerivedStateFromProps (props, state) {
if (props.color !== state.color) {
return {
color: props.color
}
}
return null
}
... // 选择颜色方法
render () {
.... // 显示颜色和选择颜色操作
}
}
纯在问题:
现在我们可以这个颜色选择器来选择颜色,同时我们能传入一个颜色值并显示。如果我们传入一个颜色值后,再使用组件内部的选择颜色方法,我们会发现颜色不会变化,一直是传入的颜色值。
这是使用这个生命周期的一个常见 bug。为什么会发生这个 bug 呢?在开头有说到,在 React 16.4^ 的版本中 setState 和 forceUpdate 也会触发这个生命周期,所以内部 state 变化后,又会走 getDerivedStateFromProps 方法,并把 state 值更新为传入的 prop。
Class ColorPicker extends React.Component {
state = {
color: '#000000',
prevPropColor: ''
}
static getDerivedStateFromProps (props, state) {
if (props.color !== state.prevPropColor) {
return {
color: props.color
prevPropColor: props.color
}
}
return null
}
... // 选择颜色方法
render () {
.... // 显示颜色和选择颜色操作
}
}
注意点:
- 因为这个生命周期是静态方法,同时要保持它是纯函数,不要产生副作用。
- 在使用此生命周期时,要注意把传入的 prop 值和之前传入的 prop 进行比较(这个 prop 值最好有唯一性,或者使用一个唯一性的 prop 值来专门比较)。
- 不使用 getDerivedStateFromProps,可以改成组件保持完全不可控模式,通过初始值和 key 值来实现 prop 改变 state 的情景。
(3) componentWillMount() / UNSAFE_componentWillMount()
componentWillMount()将在React未来版本(官方说法 17.0)中被弃用。UNSAFE_componentWillMount()在组件挂载前被调用,在这个方法中调用setState()不会起作用,是由于他在render()前被调用。
(4)render()
当他被调用时,他将计算this.props和this.state,并返回以下一种类型:
- React元素。通过jsx创建,既可以是dom元素,也可以是用户自定义的组件。
- 字符串或数字。他们将会以文本节点形式渲染到dom中。
- Portals。react 16版本中提出的新的解决方案,可以使组件脱离父组件层级直接挂载在DOM树的任何位置。
- null,什么也不渲染
- 布尔值。也是什么都不渲染。
注意:返回null,false,ReactDOM.findDOMNode(this)将会返回null,什么都不会渲染
render()方法必须是一个纯函数,他不应该改变state,也不能直接和浏览器进行交互,应该将事件放在其他生命周期函数中。
如果shouldComponentUpdate()返回false,render()不会被调用。
(5)componentDidMount
组件被装配后立即调用。
应用场景:
- 通常在这里进行ajax请求
- 初始化第三方的dom库
(6)componentWillReceiveProps()/UNSAFE_componentWillReceiveProps(nextProps)
建议使用getDerivedStateFromProps函数代替
- 当组件挂载后,接收到新的
props后会被调用 - 如果需要更新
state来响应props的更改,则可以进行this.props和nextProps的比较,并在此方法中使用this.setState()。 - 如果父组件会让这个组件重新渲染,即使
props没有改变,也会调用这个方法。 - React不会在组件初始化props时调用这个方法。调用
this.setState也不会触发。
(7) shouldComponentUpdate(nextProps, nextState)
- 渲染新的
props或state前,shouldComponentUpdate会被调用默认为true。 - 这个方法不会在初始化时被调用,也不会在
forceUpdate()时被调用。返回false不会阻止子组件在state更改时重新渲染。 - 如果
shouldComponentUpdate()返回false,componentWillUpdate,render和componentDidUpdate不会被调用。
官方并不建议在
shouldComponentUpdate()中进行深度查询或使用JSON.stringify(),他效率非常低,并且损伤性能
//下次的props和state数据
shouldComponentUpdate(nextProps,nextState){
if(nextProps.data==this.props.data){
return false
}
return true
}
(8) UNSAFE_componentWillUpdate(nextProps, nextState)
渲染新的state或props时,UNSAFE_componentWillUpdate会被调用.
将此作为在更新发生之前进行准备的机会。这个方法不会在初始化时被调用
不能在这里使用this.setState(),也不能做会触发视图更新的操作。如果需要更新state或props,调用getDerivedStateFromProps
(9) getSnapshotBeforeUpdate()
render()后的输出被渲染到DOM之前被调用。
- 它使您的组件能够在它们被潜在更改之前捕获当前值(如滚动位置)。
- 这个生命周期返回的任何值都将作为参数传递给componentDidUpdate()。
(10) componentDidUpdate(prevProps, prevState, snapshot)
在更新发生后立即调用componentDidUpdate()。
此方法不用于初始渲染。当组件更新时,将此作为一个机会来操作DOM。只要您将当前的props与以前的props进行比较(例如,如果props没有改变,则可能不需要网络请求),这也是做网络请求的好地方。
如果组件实现getSnapshotBeforeUpdate()生命周期,则它返回的值将作为第三个“快照”参数传递给componentDidUpdate()。否则,这个参数是undefined。
(11) componentWillUnmount()
在组件被卸载并销毁之前立即被调用。
在此方法中执行任何必要的清理,例如使定时器无效,取消网络请求或清理在componentDidMount中创建的任何监听。
(12) componentDidCatch(error, info)
错误边界是React组件,可以在其子组件树中的任何位置捕获JavaScript错误,记录这些错误并显示回退UI,而不是崩溃的组件树。错误边界在渲染期间,生命周期方法以及整个树下的构造函数中捕获错误。
如果类组件定义了此生命周期方法,则它将成错误边界。在它中调用setState()可以让你在下面的树中捕获未处理的JavaScript错误,并显示一个后备UI。只能使用错误边界从意外异常中恢复; 不要试图将它们用于控制流程。
错误边界只会捕获树中下面组件中的错误。错误边界本身不能捕获错误
PureComponent
PureComponent里如果接收到的新属性或者是更改后的状态和原属性、原状态相同的话,就不会去重新render了
在里面也可以使用shouldComponentUpdate,,而且。
是否重新渲染以shouldComponentUpdate的返回值为最终的决定因素。
import React, { PureComponent } from 'react'
class YourComponent extends PureComponent {
……
}
ref
对组件真正实例的引用,其实就是ReactDOM.render()返回的组件实例,ref可以挂载到组件上也可以是dom元素上。
- 挂到组件(
class声明的组件)上的ref表示对组件实例的引用。不能在函数式组件上使用 ref 属性,因为它们没有实例: - 挂载到dom元素上时表示具体的dom元素节点。
import React, { Component, createRef } from 'react'
import ReactDOM from 'react-dom'
class App extends Component {
constructor() {
super()
// 创建inputRef
this.inputRef = createRef()
}
componentDidMount () {
console.log(this.inputRef.current) // <input type="text">
}
render () {
return (
<div>
{/* 关联ref和dom */}
<input type="text" ref={this.inputRef} />
</div>
)
}
}
ReactDOM.render(
<App/>,
document.getElementById('root')
react之组件生命周期的更多相关文章
- React 之 组件生命周期
React 之 组件生命周期 理解1) 组件对象从创建到死亡它会经历特定的生命周期阶段2) React组件对象包含一系列的勾子函数(生命周期回调函数), 在生命周期特定时刻回调3) 我们在定义组件时, ...
- [React] 多组件生命周期转换关系
前段时间一直在基于React做开发,最近得空做一些总结,防止以后踩坑. 言归正传,React生命周期是React组件运行的基础,本文主要是归纳多组件平行.嵌套时,生命周期转换关系. 生命周期 Reac ...
- [深入React] 7.组件生命周期
生命周期一共分三段:初始化,运行中,销毁.按照顺序: 初始化 getDefaultProps():Object 全局只会调用一次,为当前类生成的默认props,会被父组件传入的同名props覆盖. g ...
- React Class组件生命周期
一.react组件的两种定义方式 1.函数组件,简单的函数组件像下面这样,接收Props,渲染DOM,而不关注其他逻辑 function Welcome(props) { return <h1& ...
- 【JAVASCRIPT】React学习-组件生命周期
摘要 整理组件加载过程,详细见官方文档:https://facebook.github.io/react/docs/react-component.html mount 过程 1)constructo ...
- 【React】组件生命周期
初始化阶段 getDefaultPropos:只调用一次,实力之间共享引用 getInitialState:初始化每个实例特有的状态 componentWillMount:render之前最后一次修改 ...
- React.js 小书 Lesson20 - 更新阶段的组件生命周期
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson20 转载请注明出处,保留原文链接和作者信息. 从之前的章节我们了解到,组件的挂载指的是将组件 ...
- React组件生命周期小结
React组件生命周期小结 下面所写的,只适合前端的React.(React也支持后端渲染,而且和前端有点小区别,不过我没用过.) 相关函数 简单地说,React Component通过其定义的几个函 ...
- react学习(6)——关于组件生命周期的问题
在项目开发的过程中,遇到了一个问题: 父组件请求后台数据,收到后将数据以props传给子组件,子组件根据收到数据的不同,显示不同的内容,同时,子组件自身可以根据click操作改变根据父组件的数据显示的 ...
随机推荐
- Git使用:
配置可参考: 配置name 及email:$ git config --global user.name "Your Name"$ git config --global user ...
- Java从文件路径中获取文件名的几种方法
举例:String fName =" G:\Java_Source\navigation_tigra_menu\demo1\img\lev1_arrow.gif " 方法一: 1 ...
- ks.cfg文件相关
原文转自:https://www.cnblogs.com/itzgr/p/10029631.html作者:木二 目录 一 图形化生成ks.cfg文件 二 ks.cfg文件相关项解析 一 图形化生成ks ...
- 搭建本地yum源出现:mount: 在 /dev/sr0 上找不到媒体
2021-07-27 在练习环境搭建时,因为是离线环境,故先搭建本地yum源,但是出现了一个往常没有的问题:mount: 在 /dev/sr0 上找不到媒体,参考其他博主的文章得到解决方法. 排查问题 ...
- 前端使用a标签启动本地.exe程序
目录 1,需求 2,效果图 3,实现原理 4,代码 5,注意事项 1,需求 最近有一个需求,在web页面上有一个按钮,点击按钮,调起本地的.exe程序客户端,我在网上找了很多,感觉都不完整,所以自己总 ...
- K8S资源编排(yaml)
1.yaml的格式 2.yaml的组成部分 3.yaml常用字段的含义 4.yaml编写方式 (1)方式一:使用kubectl create命令生成yaml文件,然后修改 (2)方式2:在已经部署好的 ...
- Redis的持久化机制与内存管理机制
1.概述 Redis的持久化机制有两种:RDB 和 AOF ,这两种机制有什么区别?正式环境应该采用哪种机制? 我们的服务器内存资源是有限的,如果内存被Redis的缓存占满了怎么办?这就要看Redis ...
- NOIP模拟38:b
这是T2. 一个容斥(其实也可以欧拉反演做,但是我不会). 首先开一个桶,记录第i行的j有多少个. 然后枚举1-\(maxn\),枚举他的值域内的倍数,记录倍数在第i行有多少个,将个数 ...
- Junit5快速入门指南-4
Junit5套件测试 @RunWith(JUnitPlatform.class) 执行套件 @SelectPackages({"packageA","packageB&q ...
- 动态拼接表达式——Expression
我们在项目中会遇到以下查询需求吗? 比如需要查询出满足以下条件的会员: 条件组一:30-40岁的男性会员 条件组二:20-30岁的女性会员 条件组三:60-80岁性别未知的会员 条件组内是并且关系,但 ...