笔者已经很久没写blog了,今日闲来无事写一下
咱们直译一下 useSyncExternalStore ,可以理解为使用同步外部状态
在讨论 useSyncExternalStore 之前,我们先说说什么是内部状态,外部状态和transition

内部状态

指的是像props,context,useState,useReducer这些状态

外部状态

外部则指的是一些我们可以订阅的东西,如dom中的状态,Redux里的状态等等

什么是 useTransition

useTransition 是React18里的一个新 API,在这个API的帮助下,我们可以在渲染期间保持页面可交互,换句话说,可以让React渲染暂停。(更多的细节就和并发渲染有关,这个等笔者有时间了可以再重点讨论一下。)

举例

那么useTranstion到底做了什么坏事呢?

我们知道,transition的渲染是可以被暂停的,如果有3个组件,共同用了一个状态,在渲染了第一个组件的时候,暂停了渲染,此时再渲染第二个组件,而引用的状态值发生了变化,就会导致表现形式出错(话很拗口,看图)

正常情况下
image

并发渲染情况下
image-1737274660666

对此,聪明的 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 (强烈推荐)

顺便贴一下影片中的案例链接 案例1案例2

我们不难发现,这个钩子主要面向的是外部状态,所以内部的state,context等等状态不会受到影响。而又因为在React进行暂停渲染的时候,外部状态的更新无法让React感知到。

参考:https://blog.saeloun.com/2021/12/30/react-18-usesyncexternalstore-api?ck_subscriber_id=887777478

Q.E.D.