useSyncExternalStore
外部のデータストアからの読み出しや、subscribeするために使う
たぶんv18から入った
code:ts
const state = useSyncExternalStore(
subscribe, // データストアに変更あった際に呼び出すcallback
getSnapshot, // 現在のデータストアの内容を返す
getServerSnapshot // optional. server rendering時にsnapshotを返す
);
code:ts
export function useOnlineStatus() {
return useSyncExternalStore(
subscribe(),
() => navigator.onLine,
() => true
);
}
function subscribe(callback) {
window.addEventListener('online', callback);
window.addEventListener('offline', callback);
return () => {
window.removeEventListener('online', callback);
window.removeEventListener('offline', callback);
};
}
これほんまに使い方として正しいのか?
「return () => {..}でunsubscribeする」ってdocs読んでも自明な使い方ではない
useRefを使ってref.current.addEventListenerをする時に辛い
useCallbackを使えばいいが、ref.current == nullのときの扱いで型が合わない
interfaceとして求められているものと使い方が合致してない感じがする
この記事って公式なので合ってる気がするが、歪な感じが否めない こんな
code:ts
const ref = useRef<HTMLDivElement | null>(null);
const subscribe = useCallback((callback: () => void) => {
if (ref.current == null) return () => {};
ref.current.addEventListener('contextmenu', callback);
return () => {
ref.current.removeEventListener('contextmenu', callback);
};
}, []);
useSyncExternalStore(subscribe, () => {});
たんじゅんにこれの使い方がおかしいだけか
そもそも「現在のstoreの値」など存在しない
つまり「常にaddEventLisneterはuseSYncExternalStoreに書くべき」ではない
代わりにuseSyncExternalStoreを使う
↑これは言い過ぎ
docsでも普通にuseeffectが使われている が、こっちのページではuseSyncExternalStoreの使用を推奨していた こういう感じでrefをexternal storeと見なしたらいけるかもしれない
代替策として、外部のミュータブルな値の読み取りやリッスンをするには useSyncExternalStore を利用しましょう。
第2引数は必須なん?
refが必要なとききつない??
参考