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笔记-生命周期(七)的更多相关文章

  1. 七天接手react项目 —— 生命周期&受控和非受控组件&Dom 元素&Diffing 算法

    生命周期&受控和非受控组件&Dom 元素&Diffing 算法 生命周期 首先回忆一下 vue 中的生命周期: vue 对外提供了生命周期的钩子函数,允许我们在 vue 的各个 ...

  2. 附实例!图解React的生命周期及执行顺序

    本文由云+社区发表 作者:前端林子 1.七个可选的生命周期 可以结合下图来看: (1) componentWillMount() 仅在render()方法前被调用一次,如果在该方法中调用了setSta ...

  3. react.js 生命周期componentDidUpdate的另类用法:防止页面过渡刷新

    场景:数据新增成功之后,需要返回原来的查询表,这时候的查询,需要使用react的生命周期:componentDidUpdate componentDidUpdate() 这个生命周期的作用是当prop ...

  4. React的生命周期

    我们先来看一张图,其实看完这张图基本就懂了,如果还不懂,请继续往下看. getDefaultProps 执行过一次后,被创建的类会有缓存,映射的值会存在this.props,前提是这个prop不是父组 ...

  5. React之生命周期

    哈喽,这是我的第一篇博客,请大家多多关照~ 追根溯源:What's the lifeCycle? 生命周期函数指在某一时刻组件会自动调用执行的函数: React生命周期概览: 接下来我们就着生命周期的 ...

  6. React组件生命周期小结

    React组件生命周期小结 下面所写的,只适合前端的React.(React也支持后端渲染,而且和前端有点小区别,不过我没用过.) 相关函数 简单地说,React Component通过其定义的几个函 ...

  7. React—组件生命周期详解

    React—组件生命周期详解 转自 明明的博客  http://blog.csdn.net/slandove/article/details/50748473 (非原创) 版权声明:转载请注明出处,欢 ...

  8. React 函数生命周期

      React 函数生命周期基础 1 ,概念 在组件创建.到加载到页面上运行.以及组件被销毁的过程中,总是伴随着各种各样的事件,这些在组件特定时期,触发的事件,统称为组件的生命周期:* 2,组件生命周 ...

  9. 帮你理清React的生命周期

    这是一个从印记中文 | react官方文档提取总结的,算是帮自己理清并且强化记忆React的生命周期,以便以后编写组件的时候能够有更清晰的思路.本文如有纰漏,欢迎指正 整体上来讲,React生命周期分 ...

  10. React组件,React和生命周期

    笔记,具体可以看看这个博客: https://segmentfault.com/a/1190000004168886?utm_source=tag-newest react 的jsx document ...

随机推荐

  1. HTML-CSS常用代码

    注释标签:对代码进行说明<!-- 单行注释,也可以对多行文字进行注释 -->常用格式标签<b>加粗</b> <i>斜体</i> <u& ...

  2. Blazor项目在VisualStudio调试时配置运行基础目录

    最近在使用 Blazor 开发管理后台时遇到了如下的问题,我这里后台整体采用了 AntDesignBlazor 组件库,在上线之后发现ReuseTabs组件在使用过程中,如果默认 / 没有指定为项目的 ...

  3. 换个脑袋,做个小练习------四则运算系统的随机出题的jsp实现

    四则运算出题系统网页界面的实现(别期待,只有俩操作数) index.jsp <%@ page contentType="text/html;charset=UTF-8" la ...

  4. 2019徐州网络赛 M Longest subsequence 序列自动机

    题目链接https://nanti.jisuanke.com/t/41395 题意:给两个字符串,s和t,在s中求字典序严格大于t的最长子序列. 思路:分类讨论即可.先建个s的序列自动机. 1 如果有 ...

  5. 加密脚本分析—evil.py

    加密脚本分析-evil.py 1.题目 源文件 一共两个文件 enc_flag.txt evil.py(原文件无注释) 1 # coding: utf-8 2 3 import base64 4 im ...

  6. Java面试——Tomcat

    更多内容,前往个人博客 一.Tomcat 顶层架构 ​ Tomcat 中最顶层的容器是 Server,代表着整个服务器,从上图中可以看出,一个 Server可以包含至少一个 Service,用于具体提 ...

  7. Lodash中常用函数,不建议经常使用,容易让人变懒忘了原生函数

    1.N次循环 <script type="text/javascript"> console.log('------- javascript -------'); // ...

  8. 西瓜视频的li绑定容器 踏坑之旅

    一定要绑定key,不然会出现一个li里面渲染出两个video标签

  9. abp(net core)+easyui+efcore实现仓储管理系统——ABP升级7.3下(五十九)

    Abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统--ABP总体介绍(一) abp(net core)+ ...

  10. pandas之使用自定义函数

    如果想要应用自定义的函数,或者把其他库中的函数应用到 Pandas 对象中,有以下三种方法: 1) 操作整个 DataFrame 的函数:pipe() 2) 操作行或者列的函数:apply() 3)  ...