React笔记-生命周期(七)
React笔记-生命周期(七)
生命周期值React组件从装载到卸载的全过程 在这个过程中React提供了多个内置函数供开发者在不同阶段执行需要的逻辑
状态组件由3个阶段组成 挂载阶段(MOUNTING) 更新阶段(UPDATING) 卸载阶段(UNMOUNT)
从纵向划分为2个阶段 Render阶段 Commit阶段
Render阶段 纯净且无副作用 会被React暂停 终止 重新启动
Commit阶段 可以使用DOM 有副作用
挂载阶段
constructor
构造函数(这个并不是react生命周期)
触发时机
在组件初始化时触发一次
构造函数因为在组件初始化时触发 所以是初始化state最佳位置
static getDerivedStateFromProps
触发时机
组件实例化后 重新渲染前
因此父组件更新 props变化 state更新 都会调用该函数
/**
*
* @param {*} nextProps 当前的props
* @param {*} prevState 修改前的state
* 该生命周期函数必须有返回值
* 它需要返回一个对象来更新 State
*/
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.num) {
return {
...prevState,
num: nextProps.num * 2
}
}
return prevState;
}
注意:
- 该生命周期函数是一个静态函数 所以函数内无法访问指向当前实例对象的this
- 该生命周期函数被设计成静态方法的目的是为了保持该方法的纯粹 能够起到限制开发者访问 this 也就是实例的作用 这样就不能在里面调用实例方法或者 setState 以破坏该生命周期函数的功能
- 原本该生命周期函数是被设计成 初始化、父组件更新 和 接收到 Props 才会触发,现在只要渲染就会触发,也就是 初始化 和 更新阶段 都会触发
componentWillMount
(此生命周期函数在React v17被正式废弃)
触发时机
在构造函数和装载组件(将 DOM 树渲染到浏览器中)之间触发
注意
- 在此生命周期函数里使用 setState 同步设置组件内部状态 state 将不会触发重新渲染
- 避免在该方法中引入任何的副作用(Effects)或订阅(Subscription)。对于这些使用场景,建议提前到构造函数中
render(mounting阶段)
渲染函数(这个并不是react生命周期)
作用: 仅用于渲染的纯函数 返回值取决于state和props(并不是真实渲染 返回的是一个JSX描述文件 真实渲染取决于所有组件渲染函数后)
注意
- 不能在函数中任何修改 state、props、请求数据等具有副作用的操作
- 不能读写 DOM 信息
- 不能和浏览器进行交互(例如 setTimeout)
componentDidMount
触发时机
组件完全挂载后(插入DOM树中)立即调用 后面不会再次执行这个函数
使用场景
- 渲染DOM
- 记载数据
- 网络请求
为什么在这个阶段进行网络请求
componentDidMount 这个阶段已经完成了 render,commit 阶段状态已经稳定,在这个阶段更新状态(state)不会造成冲突
实现思路
在 contructor 函数中 通过 Promise 来进行数据的请求 并且绑定到当前实例对象上 然后在 componentDidMount 中执行 Promise 把数据更新到 state 上
class Life extends React.component {
componentDidMount () {
}
}
更新阶段
componentWillReceiveProps
此生命周期函数将在React v17正式废弃 推荐使用 static getDerivedStateFromProps()代替
触发时机
- 父组件的渲染函数被调用 不论props是否改变 在渲染函数中被渲染的子组件都会经历更新阶段并触发该生命周期函数
- state更新不会触发该函数
/*
nextProps 当前的props
*/
componentWillReceiveProps(nextProps) {
}
shouldComponentUpdate
目前官方已经提供React.PureComponent 用来替代React.Component替代手写这个方法
(不需要开发者自己实现shouldComponentUpdate,就可以进行简单的判断来提升性能)触发时机
因为 state 和 props 变化而更新时 在重新渲染前该生命周期函数都会触发
使用场景
/**
*
* @param {*} nextProps 当前的props
* @param {*} nextState 当前的state
* @returns
根据逻辑判断返回 true 表示继续进行组件渲染,否则将停止组件渲染过程。默认返回 true,也就是说,只要组件触发了更新,组件就一定会更新
*/
shouldComponentUpdate (nextProps, nextState) {
return true
}
React.PureComponent纯组件
这个是用于继承 并不是生命周期(不需要开发者自己实现shouldComponentUpdate,就可以进行简单的判断来提升性能)
和React.Component相比 采用了props和state浅对比来实现shouldComponentUpdate 其他完全相同
存在问题(为什么PureComponent比较复杂的数据结构,可能会因深层的数据不一致而产生错误的否定判断)
这个方法只对state和props进行了新旧地址值比较 而没有深层对比其属性的变化 修改地址值属性不会导致页面更新(JavaScript 中的对象一般是可变的(Mutable)因为使用了引用赋值 新的对象简单的引用了原始对象 改变新的对象将影响到原始对象)
解决方法
避免修改原地址的属性 采用新对象参数更新(使用 shallowCopy(浅拷贝)或 deepCopy(深拷贝)来避免被修改) 但这样做造成了CPU和内存的浪费
componentWillUpdate
此生命周期函数将在React v17正式废弃 使用componentWillReceiveProps代替
触发时机
更新生命周期中重新渲染之前的最后一个方法 此时已经拥有了更新后的属性和状态 并且可以在这个方法中随意处理这些数据
注意
- 此函数不会在初始化渲染时候被触发
- 禁止在这个函数中调用setState方法 会造成死循环
render(updating阶段)
渲染函数 与mounting阶段的render一致 用于渲染被React处理过的JSX到浏览器
getSnapshotBeforeUpdate
触发时机
render渲染函数之前 state已更新
使用场景
获取render之前的dom状态
/**
*
* @param {*} prevProps 更新前的props
* @param {*} prevState 更新前的state
* @returns 返回值可以在componentDidUpdate中接收
*/
getSnapshotBeforeUpdate (prevProps, prevState) {
return null
}
componentDidUpdate
触发时机
组件每次重新渲染后触发 不会在初始化渲染的时候触发
注意
在此生命周期函数中使用setState 需要加if条件判断 prevProps、prevState 和 this.state 之间的数据变化 用于跳出循环
/**
*
* @param {*} prevProps 更新前的props
* @param {*} prevState 更新前的state
* @param {*} snapshot getSnapshotBeforeUpdate传过来的
*/
componentDidUpdate (prevProps, prevState, snapshot) {
}
react v17删除以下生命周期函数原因
componentWillReceiveProps | componentWillUpdate | componentWillReceiveProps
原因
被废弃的三个函数都是在render之前,因为fiber的出现,很可能因为高优先级任务的出现而打断现有任务导致它们会被执行多次
简而言之就是React官方认为开发者会在这三个函数阶段编写副作用代码(约束开发者)
卸载阶段
componentWillUnmount
触发时机
在组件卸载之前触发
使用场景
- 注销事件监听器
- 取消网络请求
- 取消定时器
- 解绑 DOM 事件
componentWillUnmount () {
}

捕获错误
static getDerivedStateFromError
触发时机
该生命周期函数会在子孙组件抛出错误时执行
import React from "react";
export default class GetDerivedStateFromError extends React.Component {
/**
*
* @param {*} error 错误信息
* @returns
* 它接收抛出的错误作为参数并且需要返回值用于更新 State
*/
static getDerivedStateFromError(error) {
return
}
render () {
return (
<div>
<div>1</div>
</div>
)
}
}
componentDidCatch
触发时机
该生命周期函数会在子孙组件抛出错误时执行
使用方式和getDerivedStateFromError一致
错误边界(Error Boundary)
一般情况下 任何组件在渲染期间发生错误 都会导致整个组件树都被卸载
错误边界是React的一个组件 这个组件可以捕获发生在任何组件树内错误 根据不同崩溃内容用页面反馈
注意
- 错误边界自身错误
- 异步错误
- 事件中错误
- 服务器渲染错误
import React, { Component } from 'react';
export default class ErrorBoundary extends Component {
state = { hasError: false };
render() {
// 发生错误时 hasError 为 false 用页面反馈
if (this.state.hasError) {
return <h1>发生错误</h1>;
}
// 没有发生错误 hasError 为 true 正常执行代码
return this.props.children;
}
// componentDidCatch生命周期函数会在子孙组件抛出错误时执行
componentDidCatch(error, info) {
this.setState({ hasError: true });
}
}
React笔记-生命周期(七)的更多相关文章
- 七天接手react项目 —— 生命周期&受控和非受控组件&Dom 元素&Diffing 算法
生命周期&受控和非受控组件&Dom 元素&Diffing 算法 生命周期 首先回忆一下 vue 中的生命周期: vue 对外提供了生命周期的钩子函数,允许我们在 vue 的各个 ...
- 附实例!图解React的生命周期及执行顺序
本文由云+社区发表 作者:前端林子 1.七个可选的生命周期 可以结合下图来看: (1) componentWillMount() 仅在render()方法前被调用一次,如果在该方法中调用了setSta ...
- react.js 生命周期componentDidUpdate的另类用法:防止页面过渡刷新
场景:数据新增成功之后,需要返回原来的查询表,这时候的查询,需要使用react的生命周期:componentDidUpdate componentDidUpdate() 这个生命周期的作用是当prop ...
- React的生命周期
我们先来看一张图,其实看完这张图基本就懂了,如果还不懂,请继续往下看. getDefaultProps 执行过一次后,被创建的类会有缓存,映射的值会存在this.props,前提是这个prop不是父组 ...
- React之生命周期
哈喽,这是我的第一篇博客,请大家多多关照~ 追根溯源:What's the lifeCycle? 生命周期函数指在某一时刻组件会自动调用执行的函数: React生命周期概览: 接下来我们就着生命周期的 ...
- React组件生命周期小结
React组件生命周期小结 下面所写的,只适合前端的React.(React也支持后端渲染,而且和前端有点小区别,不过我没用过.) 相关函数 简单地说,React Component通过其定义的几个函 ...
- React—组件生命周期详解
React—组件生命周期详解 转自 明明的博客 http://blog.csdn.net/slandove/article/details/50748473 (非原创) 版权声明:转载请注明出处,欢 ...
- React 函数生命周期
React 函数生命周期基础 1 ,概念 在组件创建.到加载到页面上运行.以及组件被销毁的过程中,总是伴随着各种各样的事件,这些在组件特定时期,触发的事件,统称为组件的生命周期:* 2,组件生命周 ...
- 帮你理清React的生命周期
这是一个从印记中文 | react官方文档提取总结的,算是帮自己理清并且强化记忆React的生命周期,以便以后编写组件的时候能够有更清晰的思路.本文如有纰漏,欢迎指正 整体上来讲,React生命周期分 ...
- React组件,React和生命周期
笔记,具体可以看看这个博客: https://segmentfault.com/a/1190000004168886?utm_source=tag-newest react 的jsx document ...
随机推荐
- ThinkPHP网站安全方案
一.ThinkPHP介绍 ThinkPHP是一款优秀的网站内容管理系统,因其功能强大,操作简单,拥有海量用户和其他CMS一样,安全漏洞也是其无法避免的问题.虽然官方不断发布补丁.升级版本,但安全问题依 ...
- redis的数据操作和python操作redis+关系非关系数据库差异
关系型数据库(RMDBS) 数据库中表与表的数据之间存在某种关联的内在关系,因为这种关系,所以我们称这种数据库为关系型数据库. 典型:Mysql/MariaDB.postgreSQL.Oracle.S ...
- 基于Centos7 minimal 加固
一.用户帐号和环境-----------------------. 2 二.系统访问认证和授权--------------------- 3 三.核心调整--------------------- 4 ...
- javaEE Web(Tomcat)深度理解 和 Servlet的本质
javaEE Web(Tomcat)深度理解 和 Servlet的本质 每博一文案 我所有的进步,只为更接近你. 上天没有给予人们公平的人生,有人拥有出奇的才能,便有人只能不辞辛苦的攀登阶梯,我默默地 ...
- 小笨自采集在线电脑壁纸 v2.0-支持移动端自适应,支持https
这周闲着没事,翻着网站,记得去年的发表的一篇文章小笨分享一款高清电脑壁纸API,主要是将孟坤壁纸改造支持https,还加了一个搜索功能.以前的壁纸是这样的: 但是,不支持移动端浏览,于是小笨趁着这周周 ...
- 在Pycharm上使用远程服务器进行调试
前言 缘起 Mac上没有GPU,需要用到学校服务器进行调试,于是产生了这篇博客.0.0bb 前提 首先确保已经将Pycharm配置好,通过SSH连接到服务器上的开发环境,这一步网络上有许多教 ...
- Hugging News #0324: 🤖️ 黑客松结果揭晓、一键部署谷歌最新大语言模型、Gradio 新版发布,更新超多!
每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...
- 常用Linux系统命令、vim编辑命令汇总(看一遍用时候来查)
基本操作 pwd命令 作用:显示当前工作目录 用法:pwd cd命令 作用:改变目录位置 用法:cd [option] [dir] cd 目录路径 -进入指定目录 cd .. -返回父目录 cd / ...
- 面向Web开发人员的Linux实用入门
从 web 开发的视角说一下在使用 Linux 时遇到的问题,主要是针对操作本身,因为指令在网上都可以查到,不会深入原理,但尽量实用. 基础认知 为什么使用 Linux 最初我使用 Linux 是因为 ...
- windows下使用pytorch进行单机多卡分布式训练
现在有四张卡,但是部署在windows10系统上,想尝试下在windows上使用单机多卡进行分布式训练,网上找了一圈硬是没找到相关的文章.以下是踩坑过程. 首先,pytorch的版本必须是大于1.7, ...