React生命周期原理与用法踩坑笔记


Posted in Javascript onApril 28, 2020

本文实例讲述了React生命周期原理与用法。分享给大家供大家参考,具体如下:

React生命周期

生命周期概览

生命周期的状态

组件的生命周期可分成三个状态:

  • Mounting:已插入真实 DOM
  • Updating:正在被重新渲
  • Unmounting:已移出真实 DOM
  • componentWillMount 在渲染前调用,在客户端也在服务端。

生命周期介绍

componentDidMount :

在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异步操作阻塞UI)。

componentWillReceiveProps

在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。

shouldComponentUpdate

返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。

可以在你确认不需要更新组件时使用。

componentWillUpdate

在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。

componentDidUpdate

在组件完成更新后立即调用。在初始化时不会被调用。

componentWillUnmount

在组件从 DOM 中移除之前立刻被调用。

代码示意

class Content extends React.Component {
 componentWillMount() {
   console.log('Component WILL MOUNT!')
 }
 componentDidMount() {
    console.log('Component DID MOUNT!')
 }
 componentWillReceiveProps(newProps) {
    console.log('Component WILL RECEIVE PROPS!')
 }
 shouldComponentUpdate(newProps, newState) {
    return true;
 }
 componentWillUpdate(nextProps, nextState) {
    console.log('Component WILL UPDATE!');
 }
 componentDidUpdate(prevProps, prevState) {
    console.log('Component DID UPDATE!')
 }
 componentWillUnmount() {
     console.log('Component WILL UNMOUNT!')
 }

React16.3生命周期

安装

在创建组件的实例并将其插入DOM时,将按以下顺序调用这些方法:

constructor()

React组件的构造函数在安装之前被调用。在实现React.Component子类的构造函数时,应该super(props)在任何其他语句之前调用。否则,this.props将在构造函数中未定义,这可能导致错误。

通常,在React中,构造函数仅用于两个目的:

通过分配对象来初始化本地状态this.state。

将事件处理程序方法绑定到实例。

不应该打电话setState()给constructor()。相反,如果您的组件需要使用本地状态,请直接在构造函数中指定初始状态this.state。

构造函数是his.state直接分配的唯一位置。在所有其他方法中,需要使用this.setState()。

static getDerivedStateFromProps()

getDerivedStateFromProps在调用render方法之前调用,无论是在初始安装还是后续更新。它应该返回一个更新状态的对象,或者返回null以不更新任何状态。

render()

render()方法是类组件中唯一必需的方法。

调用时,它应检查this.props并this.state返回以下类型之一:

  • React elements。通常通过JSX创建。
  • Arrays and fragments。让您从渲染中返回多个元素。有关更多详细信息,请参阅片段文档。
  • Portals。
  • 字符串和数字。它们在DOM中呈现为文本节点。
  • 布尔或null。什么都没有。

该render()函数应该无状态的,这意味着它不会修改组件状态,每次调用时都返回相同的结果,并且它不直接与浏览器交互。

如果您需要与浏览器进行交互,请执行componentDidMount()或其他生命周期方法。保持render()纯粹使组件更容易思考。

如果shouldComponentUpdate()返回false,则render()不会被调用

componentDidMount()

  • componentDidMount()在安装组件(插入树中)后立即调用。需要DOM节点的初始化应该放在这里。如果需要从远程端点加载数据,这是实例化网络请求的好地方。
  • 此方法是设置任何订阅的好地方。如果您这样做,请不要忘记取消订阅componentWillUnmount()。
  • 您可以在componentDidMount()立即使用this.setState()。它将触发额外的渲染,但它将在浏览器更新屏幕之前发生。这保证即使render()在这种情况下将被调用两次,用户也不会看到中间状态。请谨慎使用此模式,因为它通常会导致性能问题。在大多数情况下,您应该能够分配初始状态constructor()。但是,当您需要在渲染依赖于其大小或位置的东西之前测量DOM节点时,可能需要对模态和工具提示等情况进行处理。

这些方法被认为是遗留的,应该在新代码中避免它们:

UNSAFE_componentWillMount()

更新

props or state 的更改可能导致更新。重新渲染组件时,将按以下顺序调用这些方法:

static getDerivedStateFromProps()
render()
getSnapshotBeforeUpdate()
getSnapshotBeforeUpdate(prevProps, prevState)

getSnapshotBeforeUpdate()在最近呈现的输出被提交到例如DOM之前调用。它使得组件可以在可能更改之前从DOM捕获一些信息(例如滚动位置)。此生命周期返回的任何值都将作为参数传递给componentDidUpdate()。

此用例并不常见,但它可能出现在需要以特殊方式处理滚动位置的聊天线程等UI中。

官网的例子

class ScrollingList extends React.Component {
 constructor(props) {
  super(props);
  this.listRef = React.createRef();
 }

 getSnapshotBeforeUpdate(prevProps, prevState) {
  // Are we adding new items to the list?
  // Capture the scroll position so we can adjust scroll later.
  if (prevProps.list.length < this.props.list.length) {
   const list = this.listRef.current;
   return list.scrollHeight - list.scrollTop;
  }
  return null;
 }

 componentDidUpdate(prevProps, prevState, snapshot) {
  // If we have a snapshot value, we've just added new items.
  // Adjust scroll so these new items don't push the old ones out of view.
  // (snapshot here is the value returned from getSnapshotBeforeUpdate)
  if (snapshot !== null) {
   const list = this.listRef.current;
   list.scrollTop = list.scrollHeight - snapshot;
  }
 }

 render() {
  return (
   <div ref={this.listRef}>{/* ...contents... */}</div>
  );
 }
}

componentDidUpdate()

componentDidUpdate()更新发生后立即调用。初始渲染不会调用此方法。

将此作为在更新组件时对DOM进行操作的机会。只要您将当前道具与之前的道具进行比较(例如,如果道具未更改,则可能不需要网络请求),这也是进行网络请求的好地方。

componentDidUpdate(prevProps) {
 // Typical usage (don't forget to compare props):
 if (this.props.userID !== prevProps.userID) {
  this.fetchData(this.props.userID);
 }
}

componentDidUpdate()但要注意,必须在一个条件下被包裹就像上面的例子中,否则会导致无限循环。它还会导致额外的重新渲染,虽然用户不可见,但会影响组件性能。

componentDidUpdate():如果shouldComponentUpdate()返回false,则不会被调用。

这些方法被认为是遗留的,您应该在新代码中避免它们:

UNSAFE_componentWillUpdate()

UNSAFE_componentWillReceiveProps()

卸载

从DOM中删除组件时调用此方法:

componentWillUnmount()

componentWillUnmount()在卸载和销毁组件之前立即调用。在此方法中执行任何必要的清理,例如使计时器无效,取消网络请求或清除在其中创建的任何订阅componentDidMount()。

不应该调用setState(),componentWillUnmount()因为组件永远不会被重新呈现。卸载组件实例后,将永远不会再次安装它。

错误处理

在渲染期间,生命周期方法或任何子组件的构造函数中发生错误时,将调用这些方法。

static getDerivedStateFromError()

static getDerivedStateFromError(error)

在后代组件抛出错误后调用此生命周期。它接收作为参数抛出的错误,并应返回值以更新状态。

componentDidCatch()

componentDidCatch(error, info)

在后代组件抛出错误后调用此生命周期。它接收两个参数:

error - 抛出的错误。

info- componentStack包含键的对象,其中包含有关哪个组件引发错误的信息。

如果发生错误,可以componentDidCatch()通过调用呈现回退UI setState,但在将来的版本中将不推荐使用。使用static getDerivedStateFromError()处理回退,而不是渲染。

componentDidCatch()在“提交”阶段被调用,因此允许副作用。它应该用于记录错误之类的事情:

class ErrorBoundary extends React.Component {
 constructor(props) {
  super(props);
  this.state = { hasError: false };
 }

 static getDerivedStateFromError(error) {
  // Update state so the next render will show the fallback UI.
  return { hasError: true };
 }

 componentDidCatch(error, info) {
  // Example "componentStack":
  //  in ComponentThatThrows (created by App)
  //  in ErrorBoundary (created by App)
  //  in div (created by App)
  //  in App
  logComponentStackToMyService(info.componentStack);
 }

 render() {
  if (this.state.hasError) {
   // You can render any custom fallback UI
   return <h1>Something went wrong.</h1>;
  }
  return this.props.children; 
 }
}

希望本文所述对大家react程序设计有所帮助。

Javascript 相关文章推荐
关于二级域名下使用一级域名下的COOKIE的问题
Nov 07 Javascript
js实现点击按钮后给Div图层设置随机背景颜色的方法
May 06 Javascript
jQuery可见性过滤器:hidden和:visibility用法实例
Jun 24 Javascript
全面解析Bootstrap中nav、collapse的使用方法
May 22 Javascript
利用Javascript实现BMI计算器
Aug 16 Javascript
BootStrap无限级分类(无限极分类封装版)
Aug 26 Javascript
js动态生成form 并用ajax方式提交的实现方法
Sep 09 Javascript
实例讲解JavaScript中call、apply、bind方法的异同
Sep 13 Javascript
js实现彩色条纹滚动条效果
Mar 15 Javascript
Javascript中toFixed计算错误(依赖银行家舍入法的缺陷)解决方法
Aug 22 Javascript
jquery一键控制checkbox全选、反选或全不选
Oct 16 jQuery
如何使用VuePress搭建一个类型element ui文档
Feb 14 Javascript
js最全的数组的降维5种办法(小结)
Apr 28 #Javascript
JS数组降维的实现Array.prototype.concat.apply([], arr)
Apr 28 #Javascript
React中Ref 的使用方法详解
Apr 28 #Javascript
在Webpack中用url-loader处理图片和字体的问题
Apr 28 #Javascript
react PropTypes校验传递的值操作示例
Apr 28 #Javascript
vue 百度地图(vue-baidu-map)绘制方向箭头折线实例代码详解
Apr 28 #Javascript
Vue + Scss 动态切换主题颜色实现换肤的示例代码
Apr 27 #Javascript
You might like
第三节 定义一个类 [3]
2006/10/09 PHP
php 5.4 全新的代码复用Trait详解
2017/01/05 PHP
php获取文件名称和扩展名的方法
2017/02/07 PHP
如何利用PHP实现上传图片功能详解
2020/09/24 PHP
javascript与CSS复习(二)
2010/06/29 Javascript
基于JQuery的日期联动实现代码
2011/02/24 Javascript
Raphael带文本标签可拖动的图形实现代码
2013/02/20 Javascript
借助javascript代码判断网页是静态还是伪静态
2014/05/05 Javascript
jQuery Mobile弹出窗、弹出层知识汇总
2016/01/05 Javascript
js判断文件格式及大小的简单实例(必看)
2016/10/11 Javascript
javascript 删除数组元素和清空数组的简单方法
2017/02/24 Javascript
详解AngularJS通过ocLazyLoad实现动态(懒)加载模块和依赖
2017/03/01 Javascript
jQuery常用选择器详解
2017/07/17 jQuery
基于JS递归函数细化认识及实用实例(推荐)
2017/08/07 Javascript
jQuery实现的简单对话框拖动功能示例
2018/06/05 jQuery
微信小程序提交form操作示例
2018/12/30 Javascript
js实现直播点击飘心效果
2020/08/19 Javascript
python备份文件的脚本
2008/08/11 Python
python中尾递归用法实例详解
2015/04/28 Python
在Python中使用zlib模块进行数据压缩的教程
2015/06/26 Python
python利用socketserver实现并发套接字功能
2018/01/26 Python
pandas 把数据写入txt文件每行固定写入一定数量的值方法
2018/12/28 Python
Python数据预处理之数据规范化(归一化)示例
2019/01/08 Python
利用python、tensorflow、opencv、pyqt5实现人脸实时签到系统
2019/09/25 Python
python自动化测试无法启动谷歌浏览器问题
2019/10/10 Python
基于python实现学生信息管理系统
2019/11/22 Python
python3.6.8 + pycharm + PyQt5 环境搭建的图文教程
2020/06/11 Python
Python 生成短8位唯一id实战教程
2021/01/13 Python
韩国三大免税店之一:THE GRAND 中文免税店
2016/07/21 全球购物
太阳镜仓库,售价20美元或更少:Sunglass Warehouse
2016/09/28 全球购物
微博营销计划书
2014/01/10 职场文书
12月红领巾广播稿
2014/02/13 职场文书
文员试用期转正自我鉴定
2014/09/14 职场文书
党支部遵守党的政治纪律情况对照检查材料
2014/09/26 职场文书
介绍信范文大全
2015/05/07 职场文书
MySQL 十大常用字符串函数详解
2021/06/30 MySQL