目录
- 前言
- useSyncExternalStore 初体验
- Concurrent 模式下使用 react-redux 7
- Concurrent 模式下使用 react-redux 8
- Concurrent 模式下使用自定义 external store
- 源码分析
- useSyncExternalStore
- subscribeToStore
- pushStoreConsistencyCheck
- updateStoreInstance
- 写在最后
前言
Concurrent 模式是 React18 中最引人瞩目的新特性。通过使用 useTransition、useDeferredValue,更新对应的 reconcile 过程变为可中断,不再会因为长时间占用主线程而阻塞渲染进程,使得页面的交互过程可以更加流畅。
不过这种新特性,在给我们带来用户体验提升的同时,也给我们带来了新的挑战。在我们使用诸如 redux、mobx 等第三方状态库时,如果开启了 Concurrent 模式,那么就有可能会出现状态不一致的情形,给用户带来困扰。针对这种情况, React18 提供了一个新的 hook - useSyncExternalStore,来帮助我们解决此类问题。
今天,我们就通过本文,给大家梳理一下状态不一致的情形以及 useSyncExternalStore 的使用情形、内部原理。
useSyncExternalStore 初体验
首先说明,useSyncExternalStore 这个 hook 并不是给我们在日常项目中用的,它是给第三方类库如 Redux、Mobx 等内部使用的。
我们先来看一下官网是怎么介绍 useSyncExternalStore 的。
useSyncExternalStore is a new hook that allows external stores to support concurrent reads by forcing updates to the store to be synchronous. It removes the need for useEffect when implementing subscriptions to external data sources, and is recommended for any library that integrates with state external to React.
翻译过来就是:useSyncExternalStore 是一个新的钩子,它通过强制的同步状态更新,使得外部 store 可以支持并发读取。它实现了对外部数据源订阅时不在需要 useEffect,并且推荐用于任何与 React 外部状态集成的库。
useSyncExternalStore 这个新的 hook 的用法如下:
const value = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot )
其中,subscribe 是 external store 提供的 subscribe 方法;getSnapshot、getServerSnapshot 是用于获取指定 store 状态的方法,类似于 react-redux 中使用 useSelector 时需要传入的 selector,一个用于客户端渲染,一个用于服务端渲染;返回值就是我们在组件中可用的 store 状态。
看完上面的翻译和 api 介绍,大家是不是有点一脸懵逼呢?