官方的解释是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
- 确保服务端和客户端状态同步
内存管理
- 及时清理订阅
- 避免内存泄漏