node_modules/@react-navigation/core/lib/commonjs/useNavigationCache.js
/**
 * Hook to cache navigation objects for each screen in the navigator.
 * It's important to cache them to make sure navigation objects don't change between renders.
 * This lets us apply optimizations like `React.memo` to minimize re-rendering screens.
 */
Hook to cache navigation objects for each screen in the navigator.
It's important to cache them to make sure navigation objects don't change between renders.
This lets us apply optimizations like `React.memo` to minimize re-rendering screens.
Hook to cache navigation objects for each screen in the navigator . It ' s important to cache them to make sure navigation objects don ' t change between renders . This lets us apply optimizations like ` React . memo ` to minimize re - rendering screens .
function useNavigationCache({
  state,
  getState,
  navigation,
  setOptions,
  router,
  emitter
}) {
  const {
    stackRef
  } = React.useContext(_NavigationBuilderContext.default); 
  const cache = React.useMemo(() => ({
    current: {}
  }), 
  [getState, navigation, setOptions, router, emitter]);
  const actions = { ...router.actionCreators,
    ..._routers.CommonActions
  };
  cache.current = state.routes.reduce((acc, route) => {
    const previous = cache.current[route.key];
    if (previous) {
      acc[route.key] = previous;
    } else {
      const {
        emit,
        ...rest
      } = navigation;
      const dispatch = thunk => {
        const action = typeof thunk === 'function' ? thunk(getState()) : thunk;
        if (action != null) {
          navigation.dispatch({
            source: route.key,
            ...action
          });
        }
      };
      const withStack = callback => {
        let isStackSet = false;
        try {
          if (process.env.NODE_ENV !== 'production' && stackRef && !stackRef.current) {
            stackRef.current = new Error().stack;
            isStackSet = true;
          }
          callback();
        } finally {
          if (isStackSet && stackRef) {
            stackRef.current = undefined;
          }
        }
      };
      const helpers = Object.keys(actions).reduce((acc, name) => {
        acc[name] = (...args) => withStack(() => 
        dispatch(actions[name](...args)));
        return acc;
      }, {});
      acc[route.key] = { ...rest,
        ...helpers,
        ...emitter.create(route.key),
        dispatch: thunk => withStack(() => dispatch(thunk)),
        setOptions: options => setOptions(o => ({ ...o,
          [route.key]: { ...o[route.key],
            ...options
          }
        })),
        isFocused: () => {
          const state = getState();
          if (state.routes[state.index].key !== route.key) {
            return false;
          } 
          return navigation ? navigation.isFocused() : true;
        }
      };
    }
    return acc;
  }, {});
  return cache.current;
}
function useNavigationCache ( { state , getState , navigation , setOptions , router , emitter } ) { const { stackRef } = React . useContext ( _NavigationBuilderContext . default ) ; const cache = React . useMemo ( ( ) => ( { current : { } } ) , [ getState , navigation , setOptions , router , emitter ] ) ; const actions = { ... router . actionCreators , ... _routers . CommonActions } ; cache . current = state . routes . reduce ( ( acc , route ) => { const previous = cache . current [ route . key ] ; if ( previous ) { acc [ route . key ] = previous ; } else { const { emit , ... rest } = navigation ; const dispatch = thunk => { const action = typeof thunk === 'function' ? thunk ( getState ( ) ) : thunk ; if ( action != null ) { navigation . dispatch ( { source : route . key , ... action } ) ; } } ; const withStack = callback => { let isStackSet = false ; try { if ( process . env . NODE_ENV !== 'production' && stackRef && ! stackRef . current ) { stackRef . current = new Error ( ) . stack ; isStackSet = true ; } callback ( ) ; } finally { if ( isStackSet && stackRef ) { stackRef . current = undefined ; } } } ; const helpers = Object . keys ( actions ) . reduce ( ( acc , name ) => { acc [ name ] = ( ... args ) => withStack ( ( ) => dispatch ( actions [ name ] ( ... args ) ) ) ; return acc ; } , { } ) ; acc [ route . key ] = { ... rest , ... helpers , ... emitter . create ( route . key ) , dispatch : thunk => withStack ( ( ) => dispatch ( thunk ) ) , setOptions : options => setOptions ( o => ( { ... o , [ route . key ] : { ... o [ route . key ] , ... options } } ) ) , isFocused : ( ) => { const state = getState ( ) ; if ( state . routes [ state . index ] . key !== route . key ) { return false ; } return navigation ? navigation . isFocused ( ) : true ; } } ; } return acc ; } , { } ) ; return cache . current ; }
Hook to cache navigation objects for each screen in the navigator.
Hook to cache navigation objects for each screen in the navigator .
// Cache object which holds navigation objects for each screen // We use `React.useMemo` instead of `React.useRef` coz we want to invalidate it when deps change // In reality, these deps will rarely change, if ever // eslint-disable-next-line react-hooks/exhaustive-deps // If a cached navigation object already exists, reuse it // eslint-disable-next-line @typescript-eslint/no-unused-vars // Capture the stack trace for devtools // @ts-expect-error: name is a valid key, but TypeScript is dumb // FIXME: too much work to fix the types for now // If the current screen is focused, we also need to check if parent navigator is focused // This makes sure that we return the focus state in the whole tree, not just this navigator