位置: IT常识 - 正文

react生命周期详细介绍(react生命周期详解)

编辑:rootadmin
react生命周期详细介绍

目录

 挂载:在组件实例被创建并插入到dom中时,生命周期调用顺序如下

constructor

componentWillMount

getDerivedStateFromProps

render

componentDidMount

更新:当组件的 props 或 state 发生变化时会触发更新。

componentWillReceiveProps ()

shouldComponentUpdate

componentWillUpdate

getSnapshotBeforeUpdate

componentDidUpdate

卸载:当组件从 DOM中移除时会调用如下方法:

componentWillUnmount()

错误处理:当渲染过程,生命周期,或子组件的构造函数中抛出错误时


推荐整理分享react生命周期详细介绍(react生命周期详解),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:react的生命周期包括哪几个阶段,react生命周期setstate,react生命周期详解,react生命周期setstate,react生命周期执行顺序,react生命周期setstate,react生命周期详解,react生命周期shouldcomponentupdate,内容如对您有帮助,希望把文章链接给更多的朋友!

重新学习理解react生命周期,本文主要参考链接:

React的生命周期 - 简书

React.Component – React

React新生命周期--getDerivedStateFromProps - 简书

生命周期(旧)1 - 简书

这里我没有将新旧生命周期分开写,后面标注的可以用但是不建议使用的就是被新生命周期替换的旧生命周期。图一是旧生命周期,图二是新生命周期。

首先生命周期分为三个阶段:

        挂载:已经插入真实dom

        渲染(更新):正在被重新渲染

        卸载:已经移出真实dom

 一、挂载:在组件实例被创建并插入到dom中时,生命周期调用顺序如下

旧生命周期:

        1.constructor(props)

        2.componentWillMount()-------------可以用但是不建议使用

        3.render()

        4.componentDidMount()

新生命周期:

constructor(props)static getDerivedStateFromProps(props,state)--替代了componentWillReceivePropsrender()componentDidMount()(1)constructor

数据的初始化。

        接收props和context,当想在函数内使用这两个参数需要在super传入参数,当使用constructor时必须使用super,否则可能会有this的指向问题,如果不初始化state或者不进行方法绑定,则可以不为组件实现构造函数;

避免将 props 的值复制给 state!这是一个常见的错误:

constructor(props) { super(props); // 不要这样做 this.state = { color: props.color };}

如此做毫无必要(可以直接使用 this.props.color),同时还产生了 bug(更新 prop 中的 color 时,并不会影响 state)。

(2)componentWillMount

在挂载之前也就是render之前被调用。

        在服务端渲染唯一会调用的函数,代表已经初始化数据但是没有渲染dom,因此在此方法中同步调用 setState() 不会触发额外渲染。

(3)getDerivedStateFromProps

从props获取state。

        替代了componentWillReceiveProps,此方法适用于罕见的用例,即 state 的值在任何时候都取决于 props。

  在初始挂载和后续更新时都会被调用,返回一个对象更新state,如果返回null就不更新;如果props传入的内容不需要影响到你的state,那么就需要返回一个null,这个返回值是必须的,所以尽量将其写到函数的末尾。

static getDerivedStateFromProps(nextProps, prevState) { const {type} = nextProps; // 当传入的type发生变化的时候,更新state if (type !== prevState.type) { return { type, }; } // 否则,对于state不进行任何操作 return null;}

React的生命周期 - 简书

老版本中的componentWillReceiveProps()方法判断前后两个 props 是否相同,如果不同再将新的 props 更新到相应的 state 上去。这样做一来会破坏 state 数据的单一数据源,导致组件状态变得不可预测,另一方面也会增加组件的重绘次数。

这两者最大的不同就是: 在 componentWillReceiveProps 中,我们一般会做以下两件事,一是根据 props 来更新 state,二是触发一些回调,如动画或页面跳转等。

在老版本的 React 中,这两件事我们都需要在 componentWillReceiveProps 中去做。而在新版本中,官方将更新 state 与触发回调重新分配到了 getDerivedStateFromProps 与 componentDidUpdate 中,使得组件整体的更新逻辑更为清晰。而且在 getDerivedStateFromProps 中还禁止了组件去访问 this.props,强制让开发者去比较 nextProps 与 prevState 中的值,以确保当开发者用到 getDerivedStateFromProps 这个生命周期函数时,就是在根据当前的 props 来更新组件的 state,而不是去做其他一些让组件自身状态变得更加不可预测的事情。(4)render

class组件中唯一必须实现的方法。

render函数会插入jsx生成的dom结构,react会生成一份虚拟dom树,在每一次组件更新时,在此react会通过其diff算法比较更新前后的新旧DOM树,比较以后,找到最小的有差异的DOM节点,并重新渲染。

当render被调用时,他会检查this.props.和this.state的变化并返回以下类型之一:

  通过jsx创建的react元素  数组或者fragments:使得render可以返回多个元素  Portals:可以渲染子节点到不同的dom树上  字符串或数值类型:他们在dom中会被渲染为文本节点  布尔类型或者null:什么都不渲染

注意

        render函数是纯函数,这意味着在不修改组件state的情况下,每次调用都应该返回相同的结果,并且它不会直接和浏览器交互,如果需要和浏览器交互需要在componentDidMunt函数中或者其他生命周期函数中执行操作。

        更新过程如果 shouldComponentUpdate() 返回 false,则不会调用 render()。

(5)componentDidMountreact生命周期详细介绍(react生命周期详解)

在组件挂在后(插入到dom树中)后立即调用

        可以在这里调用Ajax请求,返回的数据可以通过setState使组件重新渲染,或者添加订阅,但是要在conponentWillUnmount中取消订阅

二、更新:当组件的 props 或 state 发生变化时会触发更新。

旧生命周期:

        1.componentWillReceiveProps (nextProps)------------------可以用但是不建议使用

        2.shouldComponentUpdate(nextProps,nextState)

        3.componetnWillUpdate(nextProps,nextState)----------------可以用但是不建议使用

        4.render()

        5.componentDidUpdate(prevProps,precState,snapshot)

新生命周期:

static getDerivedStateFromProps(nextProps, prevState)shouldComponentUpdate(nextProps,nextState)render()getSnapshotBeforeUpdate(prevProps,prevState)componentDidUpdate(prevProps,precState,snapshot)(1)componentWillReceiveProps ()

在已挂载的组件接收新的props之前调用。

通过对比nextProps和this.props,将nextProps的state为当前组件的state,从而重新渲染组件,可以在此方法中使用this.setState改变state。

componentWillReceiveProps (nextProps) { nextProps.openNotice !== this.props.openNotice&&this.setState({ openNotice:nextProps.openNotice },() => { console.log(this.state.openNotice:nextProps) //将state更新为nextProps,在setState的第二个参数(回调)可以打 印出新的state })}

        请注意,如果父组件导致组件重新渲染,即使 props 没有更改,也会调用此方法。如果只想处理更改,请确保进行当前值与变更值的比较。

        React 不会针对初始 props 调用 UNSAFE_componentWillReceiveProps()。组件只会在组件的 props 更新时调用此方法。调用 this.setState() 通常不会触发该生命周期。

(2)shouldComponentUpdate

在渲染之前被调用,默认返回为true。

        返回值是判断组件的输出是否受当前state或props更改的影响,默认每次state发生变化都重新渲染,首次渲染或使用forceUpdate时不被调用。

他主要用于性能优化,会对 props 和 state 进行浅层比较,并减少了跳过必要更新的可能性。不建议深层比较,会影响性能。如果返回false,则不会调用componentWillUpdate、render和componentDidUpdate

唯一用于控制组件重新渲染的生命周期,由于在react中,setState以后,state发生变化,组件会进入重新渲染的流程,在这里return false可以阻止组件的更新,但是不建议,建议使用 PureComponent 因为react父组件的重新渲染会导致其所有子组件的重新渲染,这个时候其实我们是不需要所有子组件都跟着重新渲染的,因此需要在子组件的该生命周期中做判断(3)componentWillUpdate

当组件接收到新的props和state会在渲染前调用,初始渲染不会调用该方法。

        shouldComponentUpdate返回true以后,组件进入重新渲染的流程,进入componentWillUpdate,不能在这使用setState,在函数返回之前不能执行任何其他更新组件的操作

此方法可以替换为 componentDidUpdate()。如果你在此方法中读取 DOM 信息(例如,为了保存滚动位置),则可以将此逻辑移至 getSnapshotBeforeUpdate() 中。

(4)getSnapshotBeforeUpdate

在最后一次渲染(提交到dom节点)之前调用,替换componetnWillUpdate

        它能在组件更改之前获取dom的节点信息(滚动位置),该方法所有返回值都会作为参数传给componentDidUpdate

和componentWillUpdate的区别

在 React 开启异步渲染模式后,在 render 阶段读取到的 DOM 元素状态并不总是和 commit 阶段相同,这就导致在 componentDidUpdate 中使用 componentWillUpdate 中读取到的 DOM 元素状态是不安全的,因为这时的值很有可能已经失效了。getSnapshotBeforeUpdate 会在最终的 render 之前被调用,也就是说在 getSnapshotBeforeUpdate 中读取到的 DOM 元素状态是可以保证与 componentDidUpdate 中一致的。

此用法并不常见,但它可能出现在 UI 处理中,如需要以特殊方式处理滚动位置的聊天线程等。应返回 snapshot 的值(或 null)例如。

//下面参考一下官网的例子class ScrollingList extends React.Component { constructor(props) { super(props); this.listRef = React.createRef(); } getSnapshotBeforeUpdate(prevProps, prevState) { // 我们是否在 list 中添加新的 items ? // 捕获滚动​​位置以便我们稍后调整滚动位置。 if (prevProps.list.length < this.props.list.length) { const list = this.listRef.current; return list.scrollHeight - list.scrollTop; } return null; } componentDidUpdate(prevProps, prevState, snapshot) { // 如果我们 snapshot 有值,说明我们刚刚添加了新的 items, // 调整滚动位置使得这些新 items 不会将旧的 items 推出视图。 //(这里的 snapshot 是 getSnapshotBeforeUpdate 的返回值) if (snapshot !== null) { const list = this.listRef.current; list.scrollTop = list.scrollHeight - snapshot; } } render() { return ( <div ref={this.listRef}>{/* ...contents... */}</div> ); }}(5)componentDidUpdate:在更新之后立即调用,首次渲染不会调用,之后每次重新渲染都会被调用。

可以在该方法调用setState,但是要包含在条件语句中,否则一直更新会造成死循环

当组件更新后,可以在此处对 DOM 进行操作。如果对更新前后的props进行了比较,可以进行网络请求。(当 props 未发生变化时,则不会执行网络请求)。

componentDidUpdate(prevProps) { // 典型用法(不要忘记比较 props): if (this.props.userID !== prevProps.userID) { this.fetchData(this.props.userID); }}

如果组件实现了 getSnapshotBeforeUpdate() 生命周期(不常用),则它的返回值将作为 componentDidUpdate() 的第三个参数 “snapshot” 参数传递。否则此参数将为 undefined。如果返回false就不会调用这个函数。

三、卸载:当组件从 DOM中移除时会调用如下方法:(1)新旧生命周期相同:componentWillUnmount():

在组件卸载和销毁之前调用

        在这执行必要的清理操作,例如,清除timer(setTimeout,setInterval),取消网络请求,或者取消在componentDidMount的订阅,移除所有监听

有时候我们会碰到这个warning:

Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the undefined component.

原因:因为你在组件中的ajax请求返回setState,而你组件销毁的时候,请求还未完成,因此会报warning 解决方法:

componentDidMount() { this.isMount === true axios.post().then((res) => { this.isMount && this.setState({ // 增加条件ismount为true时 aaa:res })})}componentWillUnmount() { this.isMount === false}componentWillUnmount() 中不应调用 setState(),因为该组件将永远不会重新渲染。组件实例卸载后,将永远不会再挂载它。四、错误处理:当渲染过程,生命周期,或子组件的构造函数中抛出错误时:static getDerivedStateFromError(error)componentDidCatch(error,info)

(1)static getDerivedStateFromError:在渲染阶段调用。

在后代组件抛出错误后被调用,他将抛出的错误作为参数,并返回一个值然后更新state

官网示例:

class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { // 更新 state 使下一次渲染可以显降级 UI return { hasError: true }; } render() { if (this.state.hasError) { // 你可以渲染任何自定义的降级 UI return <h1>Something went wrong.</h1>; } return this.props.children; }}

(2)componentDidCatch:在提交阶段被调用

在后代组件抛出错误后被调用。 它接收两个参数:

error —— 抛出的错误。info —— 带有 componentStack key 的对象,其中包含有关组件引发错误的栈信息。

它应该用于记录错误之类的情况,下面是一个官网的示例:

class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { // 更新 state 使下一次渲染可以显示降级 UI return { hasError: true }; } componentDidCatch(error, info) { // "组件堆栈" 例子: // 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) { // 你可以渲染任何自定义的降级 UI return <h1>Something went wrong.</h1>; } return this.props.children; }}

React 的开发和生产构建版本在 componentDidCatch() 的方式上有轻微差别。

在开发模式下,错误会冒泡至 window,这意味着任何 window.onerror 或 window.addEventListener('error', callback) 会中断这些已经被 componentDidCatch() 捕获的错误。

相反,在生产模式下,错误不会冒泡,这意味着任何根错误处理器只会接受那些没有显式地被 componentDidCatch() 捕获的错误。

注意

如果发生错误,你可以通过调用 setState 使用 componentDidCatch() 渲染降级 UI,但在未来的版本中将不推荐这样做。 可以使用静态 getDerivedStateFromError() 来处理降级渲染。

本文链接地址:https://www.jiuchutong.com/zhishi/300100.html 转载请保留说明!

上一篇:【微信小程序】计算器案例(微信小程序怎么制作自己的小程序)

下一篇:本地存储(Local Storage) 和 会话存储(Session Storage)(本地存储localstorage没有拿到最新值)

  • 阿里云盘9月最新可用扩容福利码汇总(阿里云盘3月公测)

    阿里云盘9月最新可用扩容福利码汇总(阿里云盘3月公测)

  • 不是资源不够就是没创意?Hi现场教你如何做好活动运营(资源不在于多少)

    不是资源不够就是没创意?Hi现场教你如何做好活动运营(资源不在于多少)

  • 小米相机打不开(小米相机打不开前置摄像头)

    小米相机打不开(小米相机打不开前置摄像头)

  • 打开qq界面是黑色的怎么办(qq界面黑屏怎么回事)

    打开qq界面是黑色的怎么办(qq界面黑屏怎么回事)

  • 荣耀手环3支持nfc吗(荣耀手环3标准版和nfc版区别)

    荣耀手环3支持nfc吗(荣耀手环3标准版和nfc版区别)

  • 微信警告教育处理对方会收到什么信息(微信警告教育处理是什么)

    微信警告教育处理对方会收到什么信息(微信警告教育处理是什么)

  • 拉黑再删除对方还能加好友吗(拉黑再删除对方还能看到聊天记录吗)

    拉黑再删除对方还能加好友吗(拉黑再删除对方还能看到聊天记录吗)

  • 抖音推送是什么意思(什么叫抖音推送)

    抖音推送是什么意思(什么叫抖音推送)

  • 美团订单极速付款是什么(美团的极速付款)

    美团订单极速付款是什么(美团的极速付款)

  • bit是字节的意思吗(bit 和字节)

    bit是字节的意思吗(bit 和字节)

  • iphonex没有面容有影响吗(iphonex没有面容解锁是什么原因)

    iphonex没有面容有影响吗(iphonex没有面容解锁是什么原因)

  • i音乐怎么收藏歌单在哪里(apple music如何收藏艺人)

    i音乐怎么收藏歌单在哪里(apple music如何收藏艺人)

  • u盘中病毒了能插电脑吗(u盘中病毒能修好吗)

    u盘中病毒了能插电脑吗(u盘中病毒能修好吗)

  • 苹果手机无线充电对电池有损害吗(苹果手机无线充电没反应是怎么回事)

    苹果手机无线充电对电池有损害吗(苹果手机无线充电没反应是怎么回事)

  • 手机瀑布屏有什么用(瀑布屏手机致命缺点)

    手机瀑布屏有什么用(瀑布屏手机致命缺点)

  • 小米mix3能用36w快充吗(小米mix3能用6a数据线吗)

    小米mix3能用36w快充吗(小米mix3能用6a数据线吗)

  • 手机上吃鸡怎么开直播?(手机上吃鸡怎么在电脑上玩)

    手机上吃鸡怎么开直播?(手机上吃鸡怎么在电脑上玩)

  • 美拍如何上传本地音乐(美拍如何上传本地文件)

    美拍如何上传本地音乐(美拍如何上传本地文件)

  • 8p录屏在哪(8p录屏在哪设置出来)

    8p录屏在哪(8p录屏在哪设置出来)

  • 虚拟机安装win7系统详细教程(win10虚拟机安装win7)

    虚拟机安装win7系统详细教程(win10虚拟机安装win7)

  • 联想G450闪屏维修实例(联想g40开机屏幕一直闪)

    联想G450闪屏维修实例(联想g40开机屏幕一直闪)

  • win11重置系统保留个人文件的方法步骤(win11重置系统保留我的文件)

    win11重置系统保留个人文件的方法步骤(win11重置系统保留我的文件)

  • 田里的拖拉机和装载着卷心菜的拖车,奥地利圣珀尔滕 (© Stephan Zirwes/Getty Images)(拖拉机拖拉机耕地)

    田里的拖拉机和装载着卷心菜的拖车,奥地利圣珀尔滕 (© Stephan Zirwes/Getty Images)(拖拉机拖拉机耕地)

  • protoize命令  添加函数原型(prompt命令用法)

    protoize命令 添加函数原型(prompt命令用法)

  • 有趣的 Go HttpClient 超时机制

    有趣的 Go HttpClient 超时机制

  • 小微企业利润表模板
  • 利息税减少
  • 境内公司没有收购的股票
  • 资产处置收益对应科目
  • 外商投资企业购买一辆小轿车自用
  • 代扣代缴城建税可以享受六税两费
  • 诉讼财产保全保险费能否主张
  • 自行建造固定资产的计税基础
  • 无偿代建政府公告
  • 中央财政补贴政策
  • 减免税款为什么在借方
  • 核定征收金额如何确定
  • 企业核算方法
  • 外购产品检验流程
  • 残疾人名下有房产可以申请残疾人补贴吗?
  • 去年的进项票今年可以抵吗
  • windows10如何开启vt
  • 路由器死机的表现
  • 小规模纳税人个税怎么申报
  • 公司从超市购买东西缴纳印花税吗
  • 苹果手机设置来电铃声怎么设置
  • php字符串函数大全
  • 拆迁货币什么意思
  • 购入固定资产后发生的员工培训费应计入固定资产的成本
  • 基本工程建设项目清单
  • mce文件是什么软件
  • php零基础教程
  • 导航菜单是什么
  • laravel 关联
  • php取值
  • 进货成本价是什么
  • 对于企业无法支付的应付账款
  • 日期选择器的()属性表示选择器的粒度
  • 专项应付款二级明细科目有哪些
  • 本年利润弥补以前年度亏损分录
  • 发给客户的服装文案
  • 其他应收账款怎么做预算会计分录
  • 公司注销时多缴税怎么办
  • python 概率分布函数
  • 各部门和单位按照国家有关规定收取或取得
  • 入库材料计入什么科目
  • 财务报表审计的基础是独立性和专业性
  • 服务器配置mysql
  • 销项发票属于哪个科目
  • 出口企业消费税怎么算
  • 车费多付了,怎么追回
  • 预付款开了发票
  • 以前年度少计提的工资怎么处理
  • 认缴制不会带来的账务问题
  • 弃置费用的摊销计算
  • 开出发票后直接做账吗?
  • 财务费用范畴
  • 居间费用超过30%违法吗
  • 商业企业购入商品
  • MySQL下载安装步骤详解
  • 谁编写了元素周期表
  • freebsd版本选择
  • 安装metpy
  • 制作win7系统安装u盘系统
  • 事件查看器中"TermService" 服务的性能库问题处理
  • explorer.exe进程100%
  • win10怎么安装运行库
  • sethook.exe - sethook进程是什么文件 有何作用
  • react增删改查功能
  • unity2d 阴影
  • gridview用法
  • bat批处理如何添加参数运行
  • jquery获取值的几种方法
  • 如何使用jquery实现点击按钮弹出一个对话框
  • Android Studio cvs 状态颜色
  • 20行的python编程题
  • 怎么实现移动
  • JavaScript中的事件处理
  • Python字符串数组
  • JQuery点击行tr实现checkBox选中的简单实例
  • 沧州地税局领导班子
  • 税控盘换新会影响旧盘数据吗
  • 江苏联通客服电话人工服务号码
  • 办理税务需要开户许可证吗
  • 审计报告非标准意见
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设