in packages/recoil/hooks/Recoil_Hooks.js [298:356]
function useRecoilValueLoadable_SYNC_EXTERNAL_STORE<T>(
recoilValue: RecoilValue<T>,
): Loadable<T> {
const storeRef = useStoreRef();
const componentName = useComponentName();
const getSnapshot = useCallback(() => {
if (__DEV__) {
recoilComponentGetRecoilValueCount_FOR_TESTING.current++;
}
const store = storeRef.current;
const storeState = store.getState();
const treeState = reactMode().early
? storeState.nextTree ?? storeState.currentTree
: storeState.currentTree;
const loadable = getRecoilValueAsLoadable(store, recoilValue, treeState);
return {loadable, key: recoilValue.key};
}, [storeRef, recoilValue]);
// Memoize the state to avoid unnecessary rerenders
const memoizePreviousSnapshot = useCallback(getState => {
let prevState;
return () => {
const nextState = getState();
if (
prevState?.loadable.is(nextState.loadable) &&
prevState?.key === nextState.key
) {
return prevState;
}
prevState = nextState;
return nextState;
};
}, []);
const getMemoizedSnapshot = useMemo(
() => memoizePreviousSnapshot(getSnapshot),
[getSnapshot, memoizePreviousSnapshot],
);
const subscribe = useCallback(
notify => {
const store = storeRef.current;
const subscription = subscribeToRecoilValue(
store,
recoilValue,
notify,
componentName,
);
return subscription.release;
},
[storeRef, recoilValue, componentName],
);
return useSyncExternalStore(
subscribe,
getMemoizedSnapshot, // getSnapshot()
getMemoizedSnapshot, // getServerSnapshot() for SSR support
).loadable;
}