@react-navigation/core
Version:
Core utilities for building navigators
60 lines (57 loc) • 2.04 kB
JavaScript
import * as React from 'react';
const UNINTIALIZED_STATE = {};
/**
* This is definitely not compatible with concurrent mode, but we don't have a solution for sync state yet.
*/
export default function useSyncState(initialState) {
const stateRef = React.useRef(UNINTIALIZED_STATE);
const isSchedulingRef = React.useRef(false);
const isMountedRef = React.useRef(true);
React.useEffect(() => {
isMountedRef.current = true;
return () => {
isMountedRef.current = false;
};
}, []);
if (stateRef.current === UNINTIALIZED_STATE) {
stateRef.current =
// @ts-expect-error: initialState is a function, but TypeScript doesn't think so
typeof initialState === 'function' ? initialState() : initialState;
}
const [trackingState, setTrackingState] = React.useState(stateRef.current);
const getState = React.useCallback(() => stateRef.current, []);
const setState = React.useCallback(state => {
if (state === stateRef.current || !isMountedRef.current) {
return;
}
stateRef.current = state;
if (!isSchedulingRef.current) {
setTrackingState(state);
}
}, []);
const scheduleUpdate = React.useCallback(callback => {
isSchedulingRef.current = true;
try {
callback();
} finally {
isSchedulingRef.current = false;
}
}, []);
const flushUpdates = React.useCallback(() => {
if (!isMountedRef.current) {
return;
}
// Make sure that the tracking state is up-to-date.
// We call it unconditionally, but React should skip the update if state is unchanged.
setTrackingState(stateRef.current);
}, []);
// If we're rendering and the tracking state is out of date, update it immediately
// This will make sure that our updates are applied as early as possible.
if (trackingState !== stateRef.current) {
setTrackingState(stateRef.current);
}
const state = stateRef.current;
React.useDebugValue(state);
return [state, getState, setState, scheduleUpdate, flushUpdates];
}
//# sourceMappingURL=useSyncState.js.map