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>

相关文章:
React 扩展
文章目录 PureComponent1. 使用 React.Component,不会进行浅比较2. 使用 shouldComponentUpdate 生命周期钩子,手动比较3. 使用 React.PureComponent,自动进行浅比较 Render Props1. 使用 Children props(通过组件标签体传入结构&…...
IT入门知识第八部分《云计算》(8/10)
目录 云计算:现代技术的新篇章 1. 云计算基础 1.1 云计算的起源和发展 云计算的早期概念 云计算的发展历程 1.2 云计算的核心特点 按需自助服务 广泛的网络访问 资源池化 快速弹性 按使用量付费 1.3 云计算的优势和挑战 成本效益 灵活性和可扩展性 维…...
Linux-笔记 全志T113移植正点4.3寸RGB屏幕笔记
目录 前言 线序整理 软件 显示调试 触摸调试 背光调试 前言 由于手头有一块4.3寸的RGB屏幕(触摸IC为GT1151),正好开发板上也有40Pin的RGB接口,就想着给移植一下,前期准备工作主要是整理好线序,然后用转接板与杜邦线连接验证好…...
Linux shell编程学习笔记59: ps 获取系统进程信息,类似于Windows系统中的tasklist 命令
0 前言 系统进程信息是电脑网络信息安全检查中的一块重要内容,对于使用Linux和基于Linux作为操作系统的电脑来说,可以使用ps命令。 1 ps命令 的功能、格式和选项说明 1.1 ps命令 的功能 Linux 中的ps(意为:process status&…...
在Android中使用ProgressBar显示进度
在Android中使用ProgressBar显示进度 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将探讨如何在Android应用中使用ProgressBar来显示进度。ProgressB…...
Java基础面试题(简单版):
1.java的8个基本数据类型? 整型: byte(占用1个字节) short(占用2个字节) int(占用4个字节) long(占用8个字节) 浮点型: float(占用4个字节)、double(占用8个字节) 字符型: char 布尔型: boolean 2.ArrayList和LinkedList的区别? 可以说ArrayList和LinkedList除了是同属于集合…...
Chrome插件:Postman Interceptor 调试的终极利器
今天给大家介绍一款非常实用的工具——Postman Interceptor。 这个工具可以捕捉任何网站的请求,并将其发送到Postman客户端。 对于经常和API打交道的程序员来说,Postman Interceptor真的是神器级别的存在。 下面就让我详细说说这个插件怎么用…...
SpringBoot学习04-[定制SpringMVC]
定制SpringMVC 定制SpringMvc的自动配置定制springmvc-configurePathMatch配置定制SpringMVC-拦截器Interceptor定制SpringMVC-CORS配置全局cors配置针对某个方法加跨域解决 WebMvcConfigurer原理定制SpringMVC-JSONJSON开发jackson的使用定制化json序列化和反序列化 JSON国际化…...
QT拖放事件之六:自定义MIME类型的存储及读取demo
1、MIME类型描述 MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的标准,用来表示文档、文件或字节流的性质和格式。 MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。 浏览器通常使用 MIME 类型(而不是文件扩展名)来确定如何处理URL…...
架构师必知的绝活-JVM调优
前言 为什么要学JVM? 首先:面试需要 了解JVM能帮助回答面试中的复杂问题。面试中涉及到的JVM相关问题层出不穷,难道每次面试都靠背几百上千条面试八股? 其次:基础知识决定上层建筑 自己写的代码都不知道是怎么回事&a…...
小米平板6系列对比
小米平板6系列目前有4款,分别为6、6 Pro、6 Max、6S Pro。具体对比如下表所示。 小米平板型号66 Pro6 Max6S Pro实物图发布时间2023年4月21日2023年4月21日2023年8月14日2024年2月22 日屏幕大小11英寸11英寸14英寸12.4英寸分辨率2.8K2.8K2.8K3K刷新率144Hz144Hz120…...
用 Rust 实现一个替代 WebSocket 的协议
很久之前我就对websocket颇有微词,它的确满足了很多情境下的需求,但是仍然有不少问题。对我来说,最大的一个问题是websocket的数据是明文传输的,这使得websocket的数据很容易遭到劫持和攻击。同时,WebSocket继承自HTTP…...
【docker】2. 编排容器技术发展史(了解)
该篇文章介绍的主要是编排以及容器技术的发展史(了解即可),如果想单纯学习docker命令操作可直接略过!!! 容器技术发展史 Jail 时代 容器不是一个新概念或者新技术,很早就有了,只是近几年遇到了云计算&am…...
吉利银河L6(官方小订送的3M) 对比 威固vk70+ks15
吉利送的号称价值2000的3M效果 撕膜重贴 威固vk70ks15 之后的效果 // 忘记测反射的热量了 可以验证金属膜是反射热而不是吸热 金属膜 手机GPS还能用吗 亲测 能用 太阳能总阻隔率 3M貌似20%出头 威固前档55% 侧后挡高一点不超过60% 夏天真实太阳发热能量 即阻隔率55%到60% …...
three.js实现雪花场景效果
点击获取雪花图片素材 提取码:lywa // 雪花效果 import * as THREE from "three" export function getsnowEffect(th) {console.log(th, th) // this 场景var that th// 创建一个BufferGeometry对象,用于存储顶点数据 const geometry new THREE.Buffe…...
鸿蒙 HarmonyOS NEXT星河版APP应用开发-阶段一
一、鸿蒙开发环境搭建 DevEco Studio安装 下载 访问官网:https://developer.huawei.com/consumer/cn/deveco-studio/选择操作系统版本后并注册登录华为账号既可下载安装包 安装 建议:软件和依赖安装目录不要使用中文字符软件安装包下载完成后࿰…...
Elasticsearch优化索引映射和设置
在Elasticsearch的世界中,优化索引的映射(mapping)和设置(settings)对于提高搜索性能、存储效率和系统稳定性至关重要。本文将带您深入了解如何针对Elasticsearch的索引进行优化,帮助您构建更高效、更可靠的…...
boss直聘招聘数据可视化分析
boss直聘招聘数据可视化分析 一、数据预处理二、数据可视化三、完整代码一、数据预处理 在 上一篇博客中,笔者已经详细介绍了使用selenium爬取南昌市web前端工程师的招聘岗位数据,数据格式如下: 这里主要对薪水列进行处理,为方便处理,将日薪和周薪的数据删除,将带有13薪…...
小程序人脸分析
公司的业务需求是用户在使用某个功能前,必须使用人脸识别,确保当前使用人是用户本人,防止某些功能乱用。后端用的是腾讯的人脸识别方案,这里只是前端的识别代码,保证人脸剧中,大小合适,有一个人…...
UML建模笔记
5个视图 设计。类,接口,对象如何协作。实现。组件,运行程序,文档关系。用例。用户功能期望。进程。并发与同步相关进程,线程。部署。部署到计算机。 建模目的 和客户共创追踪需求变更协同开发进度控制持续迭代测试生…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...
【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...
Pydantic + Function Calling的结合
1、Pydantic Pydantic 是一个 Python 库,用于数据验证和设置管理,通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发(如 FastAPI)、配置管理和数据解析,核心功能包括: 数据验证:通过…...
