作用: useSyncExternalStore
是 React 18 中引入的 Hook,用于在 React 组件中安全地订阅外部(非 React)数据源,同时保持与 React 的更新机制同步。它是 useSubscription
Hook 的官方替代,为集成如 Redux 或 MobX 这样的外部状态管理库提供了一个标准化的方式,同时支持 React 的并发模式(Concurrent Mode)。
用法: useSyncExternalStore
接受三个参数:
subscribe
:这是一个函数,它接收一个监听器(listener callback)。当外部数据源发生变化时,监听器应被调用,提示 React 需要获取新的数据快照。getSnapshot
:一个函数,返回与外部数据源当前状态相对应的值。getServerSnapshot
(可选):仅在服务端渲染(Server-Side Rendering, SSR)中使用的函数,返回与外部数据源当前状态相对应的值。
示例: 假设我们有一个简单的外部数据源 store
,它有 subscribe
和 getState
方法:
const store = {
subscribe(callback) {
// 订阅变化,当数据更新时调用 callback
},
unsubscribe(callback) {
// 取消订阅
},
getState() {
// 获取当前状态
return someData;
}
};
现在,我们可以使用 useSyncExternalStore
来订阅这个 store
:
import { useSyncExternalStore } from 'react';
function MyComponent() {
const state = useSyncExternalStore(
// 订阅函数
(callback) => {
store.subscribe(callback);
return () => store.unsubscribe(callback);
},
// 快照获取函数
() => store.getState()
);
// 使用 state 渲染你的组件
return <div>{state}</div>;
}
使用注意事项:
- 性能考虑:确保
subscribe
函数不会在组件每次渲染时都创建新的订阅,这可能会导致内存泄漏。 - 监听器调用:监听器应该被调用在任何可能导致
getSnapshot
返回值变化的情况下,以确保组件能够重新渲染。 - 避免副作用:
getSnapshot
和getServerSnapshot
应该是纯函数,它们不应有副作用,也不应更改应用状态。 - 并发模式兼容性:当使用 React 的并发模式时,
useSyncExternalStore
确保组件状态与外部数据源同步,并减少不一致的可能性。 - SSR 兼容性:确保在服务端渲染环境中提供
getServerSnapshot
函数,并处理数据获取和同步,以避免客户端和服务器的渲染不一致。
useSyncExternalStore
提供了一种标准化的方式来确保 React 组件与外部数据源保持同步,同时兼容 React 的新特性和并发模式。正确使用此 Hook 可以帮助开发者避免与状态订阅相关的常见陷阱。
原文链接:https://juejin.cn/post/7340849989742690338 作者:程序员晚天