深入理解 React 的 useSyncExternalStore Hook
深入理解 React 的 useSyncExternalStore Hook
大家好,今天我们来聊聊 React 18 引入的一个新 Hook:useSyncExternalStore。这个 Hook 主要用于与外部存储同步状态,特别是在需要确保状态一致性的场景下非常有用。本文将深入探讨这个 Hook 的使用场景、工作原理,并通过代码示例来帮助大家更好地理解。
为什么需要 useSyncExternalStore?
在 React 18 之前,我们通常使用 useEffect 或者 useLayoutEffect 来订阅外部存储的变化。然而,这些方法有时会导致状态不一致的问题,特别是在并发模式下。useSyncExternalStore 旨在解决这些问题,确保状态在任何时候都是一致的。
基本用法
首先,我们来看一下 useSyncExternalStore 的基本用法。这个 Hook 接受三个参数:
subscribe: 一个函数,用于订阅外部存储的变化。getSnapshot: 一个函数,用于获取当前的存储快照。getServerSnapshot: 一个函数,用于在服务器端渲染时获取存储快照(可选)。
import React, { useSyncExternalStore } from "react";// 模拟一个外部存储
const store = {state: 0,listeners: new Set(),subscribe(listener) {this.listeners.add(listener);return () => this.listeners.delete(listener);},setState(newState) {this.state = newState;this.listeners.forEach((listener) => listener());},getState() {return this.state;},
};function useStore() {return useSyncExternalStore(store.subscribe.bind(store),store.getState.bind(store));
}function Counter() {const state = useStore();return (<div><p>Count: {state}</p><button onClick={() => store.setState(state + 1)}>Increment</button></div>);
}export default Counter;
在这个示例中,我们创建了一个简单的计数器应用。store 是一个模拟的外部存储,包含状态和订阅逻辑。useStore 是一个自定义 Hook,使用 useSyncExternalStore 来订阅存储的变化并获取当前状态。
深入理解
useSyncExternalStore 的核心在于它如何确保状态一致性。它通过同步的方式获取存储快照,避免了异步更新带来的潜在问题。在并发模式下,React 可能会在渲染过程中多次调用 getSnapshot,以确保状态的一致性。
此外,useSyncExternalStore 还支持服务器端渲染。通过传递 getServerSnapshot 参数,我们可以在服务器端获取存储快照,从而避免客户端和服务器端渲染不一致的问题。
实际应用场景
useSyncExternalStore 非常适合用于以下场景:
- 全局状态管理:例如 Redux 或者 MobX,可以使用
useSyncExternalStore来订阅全局状态的变化。 - 外部数据源:例如 WebSocket 或者其他实时数据源,可以使用这个 Hook 来确保数据的一致性。
- 复杂组件通信:在一些复杂的组件通信场景下,使用
useSyncExternalStore可以简化状态管理逻辑。
代码示例:与 Redux 集成
接下来,我们来看一个与 Redux 集成的示例。假设我们有一个简单的 Redux store:
import { createStore } from "redux";
import { Provider, useSelector, useDispatch } from "react-redux";
import React, { useSyncExternalStore } from "react";const initialState = { count: 0 };function reducer(state = initialState, action) {switch (action.type) {case "INCREMENT":return { count: state.count + 1 };default:return state;}
}const store = createStore(reducer);function useReduxStore() {return useSyncExternalStore(store.subscribe, store.getState, store.getState);
}function Counter() {const state = useReduxStore();const dispatch = useDispatch();return (<div><p>Count: {state.count}</p><button onClick={() => dispatch({ type: "INCREMENT" })}>Increment</button></div>);
}function App() {return (<Provider store={store}><Counter /></Provider>);
}export default App;
在这个示例中,我们创建了一个 Redux store,并使用 useSyncExternalStore 来订阅 Redux store 的变化。这样,我们可以确保组件在任何时候都能获取到最新的状态。
总结
useSyncExternalStore 是 React 18 中一个非常强大的 Hook,特别适用于需要确保状态一致性的场景。通过本文的介绍和代码示例,希望大家能够更好地理解和应用这个 Hook。如果你在项目中遇到了状态不一致的问题,不妨试试 useSyncExternalStore。
百万大学生都在用的 AI 写论文工具,篇篇无重复 👉: AI 写论文
相关文章:
深入理解 React 的 useSyncExternalStore Hook
深入理解 React 的 useSyncExternalStore Hook 大家好,今天我们来聊聊 React 18 引入的一个新 Hook:useSyncExternalStore。这个 Hook 主要用于与外部存储同步状态,特别是在需要确保状态一致性的场景下非常有用。本文将深入探讨这个 Hook 的…...
河南萌新联赛2024第(一)场:河南农业大学
C-有大家喜欢的零食吗_河南萌新联赛2024第(一)场:河南农业大学 (nowcoder.com) 思路:匈牙利算法的板子题. 二部图 int n; vector<int> vct[505]; int match[505],vis[505]; bool dfs(int s){for(auto v:vct[s]){if(vis[v]) continue;…...
K8S 上部署 Emqx
文章目录 安装方式一:1. 快速部署一个简单的 EMQX 集群:2. 部署一个持久化的 EMQX 集群:3. 部署 EMQX Edge 集群和 EMQX 企业版集群: 安装方式二:定制化部署1. 使用 Pod 直接部署 EMQX Broker2. 使用 Deoloyment 部署 …...
[React]利用Webcomponent封装React组件
[React]利用Webcomponent封装React组件 为什么这么做 我个人认为,最重要的点是可以很方便地跨框架挂载和卸载wc元素(至少我在项目里是这么玩的),此外,基于wc的css沙箱以及它的shadowRoot机制,可以提供一套…...
Linux C服务需要在A服务和B服务都启动成功后才能启动
需求 C服务需要在A服务和B服务都启动成功后才能启动 服务编号服务名服务Anginx.service服务Bmashang.service服务Credis.service 实验 如果您想要 redis.service 在 nginx.service 和 mashang.service 都成功启动后才能启动,那么需要在 redis.service 的服务单元…...
VSCODE 下 openocd Jlink 的配置笔记
title: VSCODE 下 openocd Jlink 的配置笔记 tags: STM32HalCubemax 文章目录 内容VSCODE 下 openocd Jlink 的配置笔记安装完成后修改jlink的配置文件然后修改你的下载器为jlink烧录你的项目绝对会出现下面的问题那么打开下载的第一个软件 (点到这个jlink右键&…...
JVM--HostSpot算法细节实现
1.根节点枚举 定义: 我们以可达性分析算法中从GC Roots 集合找引用链这个操作作为介绍虚拟机高效实现的第一个例 子。固定可作为GC Roots 的节点主要在全局性的引用(例如常量或类静态属性)与执行上下文(例如 栈帧中的本地变量表&a…...
【Unity实战100例】Unity声音可视化多种显示效果
目录 一、技术背景 二、界面搭建 三、 实现 UIAudioVisualizer 基类 四、实现 AudioSampler 类 五、实现 IAudioSample 接口 六、实现MusicAudioVisualizer 七、实现 MicrophoneAudioManager 类 八、实现 MicrophoneAudioVisualizer 类 九、源码下载 Unity声音可视化四…...
[Cesium for Supermap] 加载3dTiles,点击获取属性
代码: // 设为椭球var obj [6378137.0, 6378137.0, 6356752.3142451793];Cesium.Ellipsoid.WGS84 Object.freeze(new Cesium.Ellipsoid(obj[0], obj[1], obj[2]));var viewer new Cesium.Viewer(cesiumContainer);var scene viewer.scenescene.lightSource.ambi…...
【stm32项目】基于stm32智能宠物喂养(完整工程资料源码)
基于STM32宠物喂养系统 前言: 随着人们生活幸福指数的提高,越来越多的家庭选择养宠物来为生活增添乐趣。然而,由于工作等原因,许多主人无法及时为宠物提供充足的食物与水。为了解决这一问题,我设计了一款便捷的宠物喂…...
选择Maya进行3D动画制作与渲染的理由
如果你对3D动画充满热情并追求成为专业3D动画师的梦想,你一定听说过Maya——近年来3D动画的行业标准。Maya被3D艺术家广泛使用,你是否想知道为什么Maya总是他们的首选?下面一起来了解下。 一、什么是Maya? 由Autodesk开发的Maya是…...
Promise应用
创建一个 Promise 对象 let promise showLabelText() {return new Promise((resolve, reject) > {axios({method: "post",url: "/code/expose/interface/queryActionPlan",data: { situationOneId: 19999, labels: [1, 2, 3] }}).then(response > {…...
51单片机嵌入式开发:13、STC89C52RC 之 RS232与电脑通讯
STC89C52RC 之 RS232与电脑通讯 第十三节课,RS232与电脑通讯1 概述2 Uart介绍2.1 概述2.2 STC89C52UART介绍2.3 STC89C52 UART寄存器介绍2.4 STC89C52 UART操作 3 C51 UART总结 第十三节课,RS232与电脑通讯 1 概述 RS232(Recommended Stand…...
当代政治制度(练习题)
当代政治制度(练习题) Rz整理 仅供参考 干部鉴定必须坚持德才兼备原则,考核内容包括(A.德 B.廉 C.能 D.勤 F.绩 ) A.德 B.廉 C.能 D.勤 E.信 F.绩我国干部任用的方式主要包括(A.考任 C.委任 D.聘任 F.选任…...
前端pc和小程序接入快递100(跳转方式和api方式)====实时查询接口
文章目录 跳转方式微信小程序(我以uniapp为例)pc api接入说明关于签名计算成功示例 跳转方式 没有任何开发成本,直接一键接入 可以直接看官方文档 https://www.kuaidi100.com/openapi/api_wxmp.shtml 微信小程序(我以uniapp为例…...
电脑永久性不小心删除了东西还可以恢复吗 电脑提示永久性删除文件怎么找回 怎么恢复电脑永久删除的数据
永久删除电脑数据的操作,对于很多常用电脑设备的用户来说,可以说时有发生!但是,因为这些情况大都发生在不经意间,所以每每让广大用户感觉到十分苦恼。永久删除也有后悔药,轻松找回电脑中误删的文件。恢复文…...
LeetCode热题100刷题16:74. 搜索二维矩阵、33. 搜索旋转排序数组、153. 寻找旋转排序数组中的最小值、98. 验证二叉搜索树
74. 搜索二维矩阵 class Solution { public:bool searchMatrix(vector<vector<int>>& matrix, int target) {int row matrix.size();int col matrix[0].size();for(int i0;i<row;i) {//先排除一下不存在的情况if(i>0&&matrix[i][0]>target…...
C++仿函数
在C中,我们经常需要对类中的元素进行比较,例如在排序、查找等操作中。为了使类更加灵活,我们可以通过自定义比较函数来实现不同的比较方式。在本文中,我们将探讨如何在类中使用仿函数和 Lambda 表达式来定义自定义比较函数。 1. …...
文献阅读:tidyomics 生态系统:增强组学数据分析
文献介绍 文献题目: The tidyomics ecosystem: enhancing omic data analyses 研究团队: Stefano Mangiola(澳大利亚沃尔特和伊丽莎霍尔医学研究所)、Michael I. Love(美国北卡罗来纳大学教堂山分校)、Ant…...
MySQL运维实战之Clone插件(10.1)使用Clone插件
作者:俊达 clone插件介绍 mysql 8.0.17版本引入了clone插件。使用clone插件可以对本地l或远程的mysql实例进行clone操作。clone插件会拷贝innodb存储引擎表,clone得到的是原数据库的一个一致性的快照,可以使用该快照数据来启动新的实例。cl…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...
