官方的解释是useSyncExternalStore
是一个让你订阅外部 store 的 React Hook。😄官方就爱打马虎眼,这样说随能一下子明白它的作用,接下来我们就来仔细的讲解下它的作用和应用场景。
useSyncExternalStore 作为 React 18 引入的一个 Hook,主要用于订阅外部数据源,确保在并发渲染下数据的一致性。它主要用于:
- 订阅浏览器 API(如 window.width)
- 订阅第三方状态管理库
- 订阅任何外部数据源
直接上例子:
-
基本语法
const state = useSyncExternalStore(
subscribe, // 订阅函数
getSnapshot, // 获取当前状态的函数
getServerSnapshot // 可选:服务端渲染时获取状态的函数
); -
实战 浏览器网络状态
//useOnlineStatus hooks
import { useSyncExternalStore } from 'react';export function useOnlineStatus() {
const isOnline = useSyncExternalStore(subscribe, getSnapshot);
return isOnline;
}function getSnapshot() {
return navigator.onLine;
}function subscribe(callback) {
window.addEventListener('online', callback);
window.addEventListener('offline', callback);
return () => {
window.removeEventListener('online', callback);
window.removeEventListener('offline', callback);
};
} -
实战浏览器窗口宽高
// useWindowSize hooks
function useWindowSize() {
const getSnapshot = () => ({
width: window.innerWidth,
height: window.innerHeight
});const subscribe = (callback) => { window.addEventListener('resize', callback); return () => window.removeEventListener('resize', callback); }; return useSyncExternalStore(subscribe, getSnapshot);
}
// 组建中 hooks使用
function NavComponent() {
const { width, height } = useWindowSize();return ( <div> Window size: {width} x {height} </div> );
}
-
实战 切换主题
function createThemeStore() {
let theme = 'light';
const listeners = new Set();return { subscribe(listener) { listeners.add(listener); return () => listeners.delete(listener); }, getSnapshot() { return theme; }, toggleTheme() { theme = theme === 'light' ? 'dark' : 'light'; listeners.forEach(listener => listener()); } };
}
const themeStore = createThemeStore();
function useTheme() {
return useSyncExternalStore(
themeStore.subscribe,
themeStore.getSnapshot
);
}function ThemeToggle() {
const theme = useTheme();return ( <button onClick={() => themeStore.toggleTheme()}> Current theme: {theme} </button> );
}
注意事项
-
保持一致性
- subscribe 函数应该返回清理函数
- getSnapshot 应该返回不可变的数据
-
避免频繁更新
- 考虑使用节流或防抖
- 实现选择性订阅机制
-
服务端渲染
- 提供 getServerSnapshot
- 确保服务端和客户端状态同步
-
内存管理
- 及时清理订阅
- 避免内存泄漏