在React應用中同步外部數據源的需求日益增長,特別是當應用需要與非React的狀態管理系統或外部API交互時。
React 18的新hook,useSyncExternalStore
,提供一種標準化的方法來安全且高效地同步這些外部數據源到React組件。本文深入探討useSyncExternalStore
的實用範例,並討論其使用中的不建議做法和常見錯誤。
useSyncExternalStore
的基本概念useSyncExternalStore
允許React組件訂閱外部數據源並在這些數據源更新時重新渲染。它主要接收三個參數:
subscribe
:函數,用於訂閱外部來源,當來源更新時應調用訂閱時提供的回調函數。getSnapshot
:函數,返回外部數據來源的當前狀態。getServerSnapshot
:(可選)函數,用於服務器渲染時獲取數據快照。假設有一個外部的數據來源需要被多個組件共享,例如用戶的登錄狀態。
設定外部數據源和訂閱機制
let userStatus = { loggedIn: false };
const listeners = new Set();
const subscribe = (listener) => {
listeners.add(listener);
return () => listeners.delete(listener);
};
const login = () => {
userStatus.loggedIn = true;
listeners.forEach(listener => listener());
};
const logout = () => {
userStatus.loggedIn = false;
listeners.forEach(listener => listener());
};
在React組件中使用useSyncExternalStore
import { useSyncExternalStore } from 'react';
function UserStatusComponent() {
const isLoggedIn = useSyncExternalStore(
subscribe,
() => userStatus.loggedIn
);
return (
<div>
Login Status:{isLoggedIn ? '已登錄' : '未登錄'}
<button onClick={login}>登入</button>
<button onClick={logout}>登出</button>
</div>
);
}
不建議的做法:
useSyncExternalStore
應當被用於那些真正需要與React組件緊密結合的外部數據源。對於不常變化或不需要React組件即時反應的數據,應考慮其他管理方案。subscribe
函數中,返回的是取消訂閱的函數。必須保證當組件卸載時取消訂閱,防止記憶體洩漏。常見錯誤:
subscribe
調用必須返回一個函數,用於取消訂閱。忽略這一點會導致應用出現記憶體洩漏。getSnapshot
函數返回的數據必須與訂閱時接收到的數據保持一致,否則會導致組件的狀態不一致。useSyncExternalStore
提供了一個標準化的方法來整合React組件和外部數據源,使開發者能夠更安全、更高效地管理跨來源的數據。使用此鉤子時應注意避免上述的不建議做法和常見錯誤,以保持應用的性能和可維護性。
其他關於hook系列文章:
關於useDeferredValue 關於useImperativeHandle 關於useSyncExternalStore 關於useTransition