笔者已经很久没写blog了,今日闲来无事写一下
咱们直译一下 useSyncExternalStore
,可以理解为使用同步外部状态
在讨论 useSyncExternalStore 之前,我们先说说什么是内部状态,外部状态和transition
内部状态
指的是像props
,context
,useState
,useReducer
这些状态
外部状态
外部则指的是一些我们可以订阅的东西,如dom中的状态,Redux里的状态等等
什么是 useTransition
useTransition 是React18里的一个新 API,在这个API的帮助下,我们可以在渲染期间保持页面可交互,换句话说,可以让React渲染暂停。(更多的细节就和并发渲染有关,这个等笔者有时间了可以再重点讨论一下。)
举例
那么useTranstion到底做了什么坏事呢?
我们知道,transition的渲染是可以被暂停的,如果有3个组件,共同用了一个状态,在渲染了第一个组件的时候,暂停了渲染,此时再渲染第二个组件,而引用的状态值发生了变化,就会导致表现形式出错(话很拗口,看图)
正常情况下
并发渲染情况下
对此,聪明的 React 团队,设计了一个新的 Api 解决这个问题,也就是今天的主角useSyncExternaStore
先贴个地址useSyncExternalStore
import { useSyncExternalStore } from 'react';
// 或者
// use-syncexternal-store/shim是React官方发布的一个用于向下兼容的套件
import { useSyncExternalStore } from 'use-syncexternal-store/shim';
// 函数的定义。getSnapshot 回传state状态
useSyncExternalStore (
subscribe: (callback) => unsubscribe, // 传入订阅的callbackFn,返回取消订阅的操作
getSnapshot: () => state
) => State;
// 使用方式
const select = useSyncExternalStore(store.subscribe, () => store.getSnapshot().select);
至于具体发生了什么,可以看这个 React 18 for External Store Libraries (强烈推荐)
我们不难发现,这个钩子主要面向的是外部状态,所以内部的state,context等等状态不会受到影响。而又因为在React进行暂停渲染的时候,外部状态的更新无法让React感知到。
参考:https://blog.saeloun.com/2021/12/30/react-18-usesyncexternalstore-api?ck_subscriber_id=887777478
Q.E.D.