React 第二十二节 useSyncExternalStore Hook 常见问题及用法详解

server/2025/2/7 9:22:16/

1、概述

在React 中我们通常会使用 useState useReducer 进行数据状态更新,但是当我们需要对外部的数据状态进行处理时候,我们需要使用React 提供的新Hook,useSyncExternalStore 让我们可以在React 内部订阅外部数据属性的状态,当订阅的外部状态发生改变时候,会触发React进行重新渲染

2、写法

const snapshot = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot?)

参数说明:

2.1、subscribe:func函数类型参数,接收一个callback 参数并把它订阅到 store 上,当 store 发生改变,它应当调用被提供的 callback。这会导致组件重新渲染。subscribe 函数会返回清除订阅的函数
2.2、getSnapshot:func函数类型参数,返回组件需要的 store 中的数据。在 store 不改变的情况下,重复调用 getSnapshot 必须返回同一个值。如果 store 改变,并且返回值也不同了(用 Object.is 比较),React 就会重新渲染组件
2.3、getServerSnapshot可选的func函数类型参数,返回 store 中数据的初始状态的快照;通常它只会在服务端渲染时,以及在客户端进行服务端渲染内容的 hydration 时被用到。快照在服务端与客户端之间【必须相同】,它通常是从服务端序列化并传到客户端的。如果你忽略此参数,在服务端渲染这个组件会抛出一个错误
2.4、snapshot: 返回值是 store的当前状态,可以在当前逻辑中进行处理

3、示例

import { useSyncExternalStore } from 'react'
let count = 0 // 初始值
let subscribers = new Set()
const store = {// 订阅subscribe(callback) {subscribers.add(callback);return () => subscribers.delete(callback);},setState(newState) {count = newState;for(const callback of subscribers) {callback()}},getSnapshot() {return count;}}export default function MySyncES() {const count = useSyncExternalStore(store.subscribe,store.getSnapshot,(prev, next) => prev === next)return (<div><p>Count: {count}</p><button onClick={() => store.setState(count + 1)}>Increment</button></div>)
}

在这个示例中,我们创建了一个简单的外部状态源 store,并使用 useSyncExternalStore 在 MySyncES 组件中同步了 的 count 状态。当点击 Increment 按钮时,我们会更新的 count 状态,useSyncExternalStore检测到状态的变化并触发 MySyncES 组件的重新渲染

需要注意的是,useSyncExternalStore 并不是用于替代 Redux、MobX 等状态管理库的工具。它更适合用于简单的状态共享场景或者与现有的状态管理库结合使用。在实际应用中,开发者应根据具体需求和场景选择合适的状态管理方案。
useSyncExternalStore 为 React 开发者提供了更灵活高效的工具来优化应用性能和用户体验。通过深入理解和实践这些特性,我们可以更好地构建出高质量的前端应用。

4、注意事项:

1、getSnapshot:返回的 store 快照必须是不可变的。若底层的store数据发生变化了,则需要在React 更新之前,返回新的不可变的快照
2、subscribe:尽量确保整个流程中的不变性与唯一性:如果在重新渲染时传入一个不同的 subscribe 函数,React 会用新传入的 subscribe 函数重新订阅该 store。你可以通过在组件外声明 subscribe 来避免。
3、如果在 非阻塞 transition 更新 过程中更改了 store,React 将会回退并将该更新视为阻塞更新。具体来说,在每次 transition 更新时,React 将在将更改应用到 DOM 之前第二次调用 getSnapshot。如果它返回的值与最初调用时不同,React 将重新从头开始进行更新,这次将其作为阻塞更新应用,以确保屏幕上的每个组件都反映 store 的相同版本。
4、不能根据 useSyncExternalStore 返回的 store 值进行条件渲染。原因是对外部 store 的变更无法 被标记为非阻塞 transition 更新,因此它们会触发最近的 Suspense 后备方案,用加载旋转器替换已经呈现在屏幕上的内容,通常会导致较差的用户体验。

注:若有错误,欢迎批评指正,共同学习进步


http://www.ppmy.cn/server/165642.html

相关文章

最大值的期望 与 期望的最大值

期望的最大值与最大值的期望 先上结论: m a x i E [ X i ] ≠ E [ m a x i X i ] max_i \mathbb{E}[X_i]\neq \mathbb{E}[max_i X_i] maxi​E[Xi​]E[maxi​Xi​] 情况一&#xff1a;最大值和数学期望都关于自变量 i i i 在这种情况下&#xff0c;最大值与期望都依赖于同一…

git bash添加tree命令

1 git bash环境没有自带tree命令 在git bash里面输入命令&#xff1a;tree&#xff0c;弹出错误如下&#xff0c;解决git Bash下安装使用tree 2 官网下载 官网下载&#xff1a;Tree for Windows 将下载的tree-1.5.2.2-bin.zip解压&#xff0c;将tree-1.5.2.2-bin\bin\tree.…

Go-Gin Web 框架完整教程

1. 环境准备 1.1 Go 环境安装 Go 语言&#xff08;或称 Golang&#xff09;是一个开源的编程语言&#xff0c;由 Google 开发。在开始使用 Gin 框架之前&#xff0c;我们需要先安装 Go 环境。 安装步骤&#xff1a; 访问 Go 官网下载页面&#xff1a;https://golang.org/dl…

app专项测试(网络测试流程)

一、网络测试的一般流程 step1&#xff1a;首先要考虑网络正常的情况 ① 各个模块的功能正常可用 ② 页面元素/数据显示正常 step2&#xff1a;其次要考虑无网络的情况 ① APP各个功能在无网络情况下是否可用 ② APP各个页面之间切换是否正常 ③ 发送网络请求时是…

langchain教程-3.OutputParser/输出解析

前言 该系列教程的代码: https://github.com/shar-pen/Langchain-MiniTutorial 我主要参考 langchain 官方教程, 有选择性的记录了一下学习内容 这是教程清单 1.初试langchain2.prompt3.OutputParser/输出解析4.model/vllm模型部署和langchain调用5.DocumentLoader/多种文档…

大模型—Dify本地化部署实战

Dify本地化部署实战 系统要求 安装 Dify 之前, 请确保你的机器已满足最低安装要求: CPU >= 2 CoreRAM >= 4 GiB本地部署 开始前先简单介绍下部署Dify需要用到的组件,稍微有点多,但放心,有Docker你怕啥? 关系数据库:postgres缓存:Redis向量数据库:支持weaviate…

现代C++多线程基础 - 忆苦思甜pthread

c 进程 线程 进程 概念 进程控制块 PCB 进程控制块就是用于保存一个进程信息的结构体&#xff0c;又称之为PCB process state 进程状态process number 进程由pid唯一标记。program counter PC值registers 寄存器的值memory limits 内存中的管理信息 (起始地址 空间 虚拟内…

1992-2025年中国计算机发展状况:服务器、电脑端与移动端的演进

1992-2025年中国计算机发展状况&#xff1a;服务器、电脑端与移动端的演进 一、1992-2000年&#xff1a;市场化转型与基础积累 背景&#xff1a;改革开放深化&#xff0c;计算机产业从科研导向转向市场化&#xff0c;但核心技术仍依赖进口。 1. 服务器领域 技术基础&#xff1…