认识
一、认识
Zustand
相较于 React-Redux
的优势在于其极简且直观的 API
设计,无需繁琐的 action
、reducer
和中间件配置, 无需繁杂的样板代码, 通过闭包和订阅机制实现了精准更新, 确保组件只在真正需要时才重新渲染, 同时支持状态切片和选择器,使得组件能够只订阅所需数据。再加上与 React 18
的 useSyncExternalStore
无缝衔接, 能够在并发模式下保持数据一致性和高性能, 借助 useSyncExternalStore
与选择器使组件仅订阅所需状态,从而减少不必要的重渲染。同时它不依赖于 React Context
,避免了大规模状态更新时的性能瓶颈,使用起来更符合现代 React Hooks
编程风格,学习曲线更低,适用于从小型到大型应用,而 Redux
尽管拥有丰富的生态系统和强大的中间件支持,但往往需要更多样板代码和复杂的架构来管理状态。
useSyncExternalStore
是 React 18
引入的一个内置 Hook
, 专门用于解决外部数据源(比如 Redux``、Zustand
等状态管理库)与 React
组件之间的数据同步问题。它的主要作用是让组件在渲染期间能够安全、一致地读取外部 store
的状态快照, 同时在 store
发生变化时,自动触发组件重新渲染,从而确保 UI
始终与外部状态保持同步。具体来说,它需要你提供两个核心函数:
-
subscribe
: 一个函数, 接收一个单独的callback
参数并把它订阅到store
上。当store
发生改变时会调用提供的callback
,这将导致React
重新调用getSnapshot
并在需要的时候重新渲染组件。subscribe
函数会返回清除订阅的函数。换句话说:subscribe
的作用就是让每个使用store
的组件都能注册自己的订阅回调。当store
更新时, 我们手动调用订阅回调, 从而让相应的组件通过getSnapshot
获取最新状态并触发重新渲染。所以subscribe
注册的回调数目实际上就反映了当前有多少组件(或其他订阅者)在关注这个store
的变化,同时它也支持取消订阅以避免不必要的更新。 -
getSnapshot
: 一个函数,返回组件需要的store
中的数据快照。在store
不变的情况下,重复调用getSnapshot
必须返回同一个值。如果store
改变,并且返回值也不同了(用Object.is
比较),React
就会重新渲染组件。 -
返回值: 该
store
的当前快照,可以在你的渲染逻辑中使用。
Zustand
的 create
实现逻辑基于 useSyncExternalStore
, 通过 subscribe
参数来收集所有订阅该 Store
的组件的通知更新回调。通过 getSnapshot
来传递给 store
当前数据状态。当修改 store
数据后, 会循环遍历订阅 Store
的组件通知更新回调, React
会重新调用 getSnapshot
, 并通过 Object.is
来比较前后状态, 如果发生变化, 在需要的时候重新渲染组件。因此, Zustand
的 create
通过 useSyncExternalStore subscribe 与 getSnapshot
的结合, 实现组件对外部状态的精准订阅和更新, 从而构建出一个轻量高效且易于扩展的状态管理解决方案。