React的API✅
createContext
createContext要和useContext配合使用,可以理解为 “React自带的redux或mobx” ,事实上redux就是用context来实现的。但是一番操作下来我还是感觉,简单的context对视图的更新的细粒度把控比不上mobx,除非配合memo等优化手段来优化。(redux只用过一次不是很会👋)
以下demo介绍context的简单使用:
// store.ts
import { createContext } from "react";
export const ThemeContext = createContext({theme: "light",setTheme: (_theme: string): void => {},
});
export const AuthContext = createContext({name: "boyiao",roleType: "admin",setRoleType: (_roleType: string): void => {},setName: (_name: string): void => {},
});
// Demo.js
import { useContext, useState } from "react";
import { ThemeContext, AuthContext } from "./store";const PageA = () => {console.log("Page Render");const { theme, setTheme } = useContext(ThemeContext);const { name, setName, roleType, setRoleType } = useContext(AuthContext);return (<div><button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>Set Theme In Page</button><div>{theme}</div><div>{name}</div></div>);
};const OtherPage = () => {console.log("OtherPage Render");return (<div style={{ border: "1px solid red" }}><div>OtherPage</div></div>);
};function Demo() {const [theme, setTheme] = useState("light");const [name, setName] = useState("boyiao");const [roleType, setRoleType] = useState("admin");console.log("App Render");return (<><ThemeContext.Provider value={{ theme, setTheme }}><AuthContext.Provider value={{ name, setName, roleType, setRoleType }}><button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>Change Theme</button><button onClick={() => setRoleType(roleType === "admin" ? "user" : "admin")}>Change Auth</button><Page /></AuthContext.Provider></ThemeContext.Provider><OtherPage /> // 注意这玩意在Context之外</>);
}export default Demo;
为什么说“简单的context对视图的更新的细粒度把控比不上mobx”?项目中常见的情况是,我们有一些需要在全局共享的状态需要管理如userName、roleType、themeToken等,如果用context来管理,为了保证这些变量可改变并触发视图重新渲染,我们不得不在根组件里用useState来保存这些全局变量。但是如果这些全局的变量改变,重新渲染影响到的范围是从最顶层往下的,成本未免太高。
见上面那个demo,OtherPage不会用到context中的变量,但是每次全局变量更新,OtherPage也要重新渲染。
但是当然有办法解决, 用memo、useMemo来缓存就好了;或者我们把需要共享的变量进行一些作用域的划分,即不要把所有需要共享的变量都生命在Root组件里面,这些都是为了降低重绘(排)的成本, 只是需要在别的地方下点功夫。只是如果用mobx则方便很多,因为mobx要求开发者用observer来显示地绑定要监听的组件:
// store.ts
import { observable, configure, action } from "mobx";
configure({ enforceActions: "always" });
interface AccountMobx {userName: string;roleType: "admin" | "user";setUserName: (name: string) => void;setRoleType: (role: "admin" | "user" ) => void;
}
const accountMobx = observable<AccountMobx>({userName: "boyiao",roleType: "admin",setUserName(name: string) {this.userName = name;},setRoleType(role: "admin" | "user" ) {this.roleType = role;},},{setUserName: action,setRoleType: action}
);
export default accountMobx;
import { observer } from "mobx-react-lite";
import accountMobx from "./store";
const Demo = observer(() => {console.log("Demo render");return (<div><div>{accountMobx.userName}</div><buttononClick={() => accountMobx.setUserName(accountMobx.userName + "1")}>set userName</button></div>);
});
export default Demo;
import "./App.css";
import Demo from './ReactMobxDemo/index.tsx'
function App() {console.log("App rendered");return (<><Demo /><div className="App">// App Content</div></>);
}
export default App;
这样的好处很直接:Demo的更新影响不到App中的其他内容。
错误边界
只用过类组件的,主要借助类组件的 componentDidCatch (他可以捕获子组件渲染过程中的错误,并在渲染组件树的过程中向上冒泡,直到它被捕获为止。)生命周期。函数组件要实现这种功能相对复杂。
import React from "react";
class ErrorBoundary extends React.Component {constructor(props) {super(props);this.state = { hasError: false };}static getDerivedStateFromError(error) {// 更新状态以干掉后续的渲染return { hasError: true };}componentDidCatch(error, errorInfo) {// 可以在此处记录错误信息console.error("错误捕获:", error, errorInfo);}render() {if (this.state.hasError) {// 自定义的降级 UIreturn <h1>出了点问题,请稍后再试。</h1>;}return this.props.children;}
}
伟大无需多言。
createPoral(React DOM的API)
最近发布了一个图钉组件📌到npm上面,这个组件的实现就是借助了createPoral。
portal 允许组件将它们的某些子元素渲染到 DOM 中的不同位置。这使得组件的一部分可以“逃脱”它所在的容器。例如组件可以在页面其余部分上方或外部显示模态对话框和提示框。
portal 只改变 DOM 节点的所处位置。在其他方面,渲染至 portal 的 JSX 的行为表现与作为 React 组件的子节点一致。该子节点可以访问由父节点树提供的 context 对象、事件将从子节点依循 React 树冒泡到父节点。
考虑下面这个需求:在我的React应用中有一个比待标记的节点,我希望将它标记出来:即在页面的空白处打上一个「图钉」,并将「图钉」与这个「待标记的节点」用线连接(怎么画线先不管,在我的组件里我用div来做,这么简单怎么来)。
然后我希望实现的代码逻辑如下:
const HomePage = () => {return (<div id="container"><div id="targetDOM">这是你想要连接的元素</div><ThumbtackpopupContainerId="container"targetElementId="targetDOM"></Thumbtack></div>);
};
问题来了:Thumbtack要如何封装,才能让他里面的某些DOM节点跑到#container里面,和#targetDOM产生交互?这就是createPoral的作用。
const Thumbtack = ({popupContainerId,targetElementId
}: { popupContainerId: string,targetElementId: string
}) => {const [popupContainer, setPopupContainer] = useState(null);useEffect(() => {const popupRef = document.getElementById(popupContainerId);popupRef && setPopupContainer(popupRef);}, [])return (<div id='thumbtack'>{ popupContainer && createPortal(<div>📌</div>, popupContainer) }</div>)
}
最基本的思路就如上面这样简单,把📌挂载到和#targetDOM的同一个父节点下面,方便后续的绝对定位、transform等操作。但是createPoral改变的只是DOM元素渲染的位置,在上面那个Thumbtack中,< div>📌< /div>可以使用在Thumbtack里面定义的变量,而且他的事件冒泡也是冒泡到#thumbtack那里,而非#container那里。
forwardRef
forwardRef最常见的还是配合useImperativeHandle一块用,但单独使用也可以把自组件的某些DOM节点暴露给父组件。我都懒得写了直接看人家React官网吧。
keep-alive在react里如何实现?
- 现有的方案:react-activation
- 推荐关注的:React18 的 Offscreen
- 自己实现:保留关键数据(如滚动的距离、需要记录的关键状态……)
相关文章:
React的API✅
createContext createContext要和useContext配合使用,可以理解为 “React自带的redux或mobx” ,事实上redux就是用context来实现的。但是一番操作下来我还是感觉,简单的context对视图的更新的细粒度把控比不上mobx,除非配合memo等…...
什么是全渠道客服中心?都包括哪些电商平台?
什么是全渠道客服中心?都包括哪些电商平台? 作者:开源呼叫中心系统 FreeIPCC,Github地址:https://github.com/lihaiya/freeipcc 全渠道客服中心是一种能够同时接入并处理来自多个渠道客户咨询和请求的综合服务平台。以…...
Jtti:如何知晓服务器的压力上限?具体的步骤和方法
了解服务器的压力上限(也称为性能极限或容量)是确保系统在高负载下仍能稳定运行的重要步骤。这通常通过压力测试(也称为负载测试或性能测试)来实现。以下是详细的步骤和方法来确定服务器的压力上限: 1. 定义测试目标和指标 在进行压力测试前,明确测试目标…...
贪心算法(1)
目录 柠檬水找零 题解: 代码: 将数组和减半的最少操作次数(大根堆) 题解: 代码: 最大数(注意 sort 中 cmp 的写法) 题解: 代码: 摆动序列࿰…...
SpringBoot,IOC,DI,分层解耦,统一响应
目录 详细参考day05 web请求 1、BS架构流程 2、RequestParam注解 完成参数名和形参的映射 3、controller接收json对象,使用RequestBody注解 4、PathVariable注解传递路径参数 5、ResponseBody(return 响应数据) RestController源码 6、统一响…...
目标驱动学习python动力
文章目录 迟迟未开始的原因打破思维里的围墙抛砖引玉爬虫 结束词 迟迟未开始的原因 其实我也是很早就知道有python,当时听说这个用于做测试不错,也就一直没有提起兴趣,后来人工智能火了之后,再次接触python,安装好pyth…...
力扣-Hot100-回溯【算法学习day.39】
前言 ###我做这类文档一个重要的目的还是给正在学习的大家提供方向(例如想要掌握基础用法,该刷哪些题?)我的解析也不会做的非常详细,只会提供思路和一些关键点,力扣上的大佬们的题解质量是非常非常高滴&am…...
小熊派Nano接入华为云
一、华为云IoTDA创建产品 创建如下服务,并添加对应的属性和命令。 二、小熊派接入 根据小熊派官方示例代码D6完成了小熊派接入华为云并实现属性上传命令下发。源码:小熊派开源社区/BearPi-HM_Nano 1. MQTT连接代码分析 这部分代码在oc_mqtt.c和oc_mq…...
【linux硬件操作系统】计算机硬件常见硬件故障处理
这里写目录标题 一、故障排错的基本原则二、硬件维护注意事项三、关于最小化和还原出厂配置四、常见故障处理及调试五、硬盘相关故障六、硬盘相关故障:硬盘检测问题七、硬盘相关故障:自检硬盘报错八、硬盘相关故障:硬盘亮红灯九、硬盘相关故障…...
谈学生公寓安全用电系统的涉及方案
学生公寓安全 学生公寓安全用电系统的设计方案主要包括以下几个方面: 电气线路设计: 合理布线:确保所有电气线路按照国家或地区的电气安全标准进行设计,避免线路过载和短路。使用阻燃材料:选用阻燃或低…...
自动语音识别(ASR)与文本转语音(TTS)技术的应用与发展
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
Go 语言数组
Go 语言数组 引言 Go 语言是一种静态类型、编译型语言,由 Google 开发,旨在提高多核处理器下的编程效率。数组作为 Go 语言中的一种基本数据结构,提供了存储一系列具有相同类型元素的能力。本文将深入探讨 Go 语言中数组的使用方法、特性以…...
13. 【.NET 8 实战--孢子记账--从单体到微服务】--简易权限--完善TODO标记的代码
这篇文章特别短,短到可以作为一篇文章的一个章节,那让我们开始吧 一、编写代码 我们在代码中标记了大量的TODO标记,并且注明了这里暂时写死,等权限和授权完成后再改为动态获取这句话。那么到目前为止和权限有关的代码已经完成了…...
深入剖析Java内存管理:机制、优化与最佳实践
🚀 作者 :“码上有前” 🚀 文章简介 :Java 🚀 欢迎小伙伴们 点赞👍、收藏⭐、留言💬 深入剖析Java内存管理:机制、优化与最佳实践 一、Java内存模型概述 1. Java内存模型的定义与作…...
【Amazon】亚马逊云科技Amazon DynamoDB 实践Amazon DynamoDB
Amazon DynamoDB 是一种完全托管的 NoSQL 数据库服务,专为高性能和可扩展性设计,特别适合需要快速响应和高吞吐量的应用场景,如移动应用、游戏、物联网和实时分析等。 工作原理 Amazon DynamoDB 在任何规模下响应时间一律达毫秒级ÿ…...
Qt-常用的显示类控件
QLabel QLabel有如下核心属性: 关于文本格式的验证: 其中<b>xxx<b>,就是加粗的意思。 效果: 或者再把它改为markdown形式的: 在markd中,#就是表示一级标题,我们在加上##后&#x…...
LabVIEW内燃机缸压采集与分析
基于LabVIEW开发的内燃机缸压采集与分析系统结合高性能压力传感器和NI数据采集设备,实现了内燃机工作过程中缸压的实时监测与分析,支持性能优化与设计改进。文中详细介绍了系统的开发背景、硬件组成、软件设计及其工作原理,展现了完整的开发流…...
【Linux学习】【Ubuntu入门】1-7 ubuntu下磁盘管理
1.准备一个U盘或者SD卡(插上读卡器),将U盘插入主机电脑,右键点击属性,查看U盘的文件系统确保是FAT32格式 2.右键单击ubuntu右下角图标,将U盘与虚拟机连接 参考链接 3. Ubuntu磁盘文件:/dev/s…...
VScode clangd插件安装
前提 在VScode中写C代码时,总会用到 C/C 这个插件,也就自然而然地使用了这个插件带来的代码跳转和代码提示功能。但是当代码变地很多时,就会变得非常慢。所以经过调查后弃用C/C 插件的这个功能,使用 clangd 这个插件来提示C代码和…...
【机器学习】- L1L2 正则化操作
目录 0.引言1.正则化的基本思想2.L1 正则化3.L2 正则化4.L1 与 L2 正则化的比较5.应用:控制模型复杂度6.超参数 λ \lambda λ 的选择7.总结 0.引言 在机器学习中,正则化是一种通过约束模型参数来控制模型复杂度的技术。它可以有效减少过拟合ÿ…...
8255A工作方式0实战:手把手教你用汇编语言驱动八路抢答器LED与数码管
8255A工作方式0实战:从零构建八路抢答器驱动框架 记得第一次在实验室见到8255A芯片时,那块黑色的DIP封装器件看起来平平无奇,直到它让八颗LED随着我的汇编指令跳起"灯光芭蕾"。本文将带你深入这个经典可编程并行接口芯片的实战应用…...
小白也能搞定!用Docker和Halo 2.10搭建个人博客,再也不用担心公网访问问题
零基础玩转DockerHalo 2.10:打造高颜值个人博客全攻略 在数字内容创作爆发的时代,拥有一个专属博客空间已成为个人品牌建设的标配。但传统建站方案往往面临技术门槛高、维护成本大等痛点。本文将带你用Docker容器技术和Halo 2.10开源系统,30…...
环境感知驱动的EFI构建:让OpenCore配置效率提升300%
环境感知驱动的EFI构建:让OpenCore配置效率提升300% 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify OpenCore配置(OpenCore是一…...
Polars 2.0清洗架构解密(含完整数据流拓扑图):为什么92%的团队还在用Pandas硬扛TB级脏数据?
第一章:Polars 2.0清洗架构解密:从设计哲学到性能跃迁Polars 2.0 的清洗架构并非简单功能叠加,而是以“零拷贝流式处理”与“惰性执行图优化”为双核驱动的范式重构。其设计哲学根植于两个核心信条:数据不应在内存中被无谓复制&am…...
ESP WiFi中继器终极配置指南:从零开始打造智能无线网络扩展器
ESP WiFi中继器终极配置指南:从零开始打造智能无线网络扩展器 【免费下载链接】esp_wifi_repeater A full functional WiFi Repeater (correctly: a WiFi NAT Router) 项目地址: https://gitcode.com/gh_mirrors/es/esp_wifi_repeater 想要轻松扩展WiFi覆盖范…...
Vlc.DotNet:在.NET应用中构建专业级媒体播放能力
Vlc.DotNet:在.NET应用中构建专业级媒体播放能力 【免费下载链接】Vlc.DotNet .NET control that hosts the audio/video capabilities of the VLC libraries 项目地址: https://gitcode.com/gh_mirrors/vl/Vlc.DotNet 价值定位:解决.NET媒体播放…...
告别枯燥刷怪!用Python+大漠插件实现《功夫》游戏后台自动挂机(附完整源码)
用Python与大漠插件打造《功夫》游戏智能挂机系统 在角色扮演类游戏中,重复性的任务往往成为玩家体验的瓶颈。以经典游戏《功夫》为例,"考古"任务需要不断接取、放弃任务直至找到特定地点,再完成打怪流程。这种机械操作不仅耗时耗力…...
OpenClaw对接Qwen3-VL:30B:飞书智能助手配置
OpenClaw对接Qwen3-VL:30B:飞书智能助手配置 1. 为什么选择这个组合? 去年我在团队内部尝试搭建一个能处理图片和文本的智能助手时,遇到了三个痛点:一是商业API调用成本太高,二是数据安全性无法保证,三是…...
DeepSeek LintCode 3866.有效子数组的数量 public int validSubarrays(int[] nums)
这是关于LintCode 3866 “有效子数组的数量”的问题。这是一个典型的单调栈应用问题,需要计算数组中所有满足特定条件的子数组数量。 问题理解 有效子数组的定义: 对于数组 nums 中的某个子数组 nums[i..j](i ≤ j),如…...
2026 ASNT-TC-1A 无损检测 Ⅱ/Ⅲ 级认证指南|API/ASME 认证必备 + 报考实操
一、行业刚需:为何 ASNT-TC-1A 资质是工业检测领域的「硬通货」在石油天然气、压力容器、钢结构焊接等工业领域,无损检测(NDT)是产品质量保障的核心环节,而ASNT-TC-1A作为美国无损检测学会制定的人员资格鉴定和认证标准…...
