UNPKG

8.64 kBSource Map (JSON)View Raw
1{"version":3,"names":["CommonActions","React","NavigationBuilderContext","useNavigationCache","state","getState","navigation","setOptions","router","emitter","stackRef","useContext","cache","useMemo","current","actions","actionCreators","routes","reduce","acc","route","previous","key","emit","rest","dispatch","thunk","action","source","withStack","callback","isStackSet","process","env","NODE_ENV","Error","stack","undefined","helpers","Object","keys","name","args","create","getParent","id","getId","options","o","isFocused","index"],"sources":["useNavigationCache.tsx"],"sourcesContent":["import {\n CommonActions,\n NavigationAction,\n NavigationState,\n ParamListBase,\n Router,\n} from '@react-navigation/routers';\nimport * as React from 'react';\n\nimport NavigationBuilderContext from './NavigationBuilderContext';\nimport type { NavigationHelpers, NavigationProp } from './types';\nimport type { NavigationEventEmitter } from './useEventEmitter';\n\ntype Options<\n State extends NavigationState,\n EventMap extends Record<string, any>\n> = {\n state: State;\n getState: () => State;\n navigation: NavigationHelpers<ParamListBase> &\n Partial<NavigationProp<ParamListBase, string, any, any, any>>;\n setOptions: (\n cb: (options: Record<string, object>) => Record<string, object>\n ) => void;\n router: Router<State, NavigationAction>;\n emitter: NavigationEventEmitter<EventMap>;\n};\n\ntype NavigationCache<\n State extends NavigationState,\n ScreenOptions extends {},\n EventMap extends Record<string, any>\n> = Record<\n string,\n NavigationProp<\n ParamListBase,\n string,\n string | undefined,\n State,\n ScreenOptions,\n EventMap\n >\n>;\n\n/**\n * Hook to cache navigation objects for each screen in the navigator.\n * It's important to cache them to make sure navigation objects don't change between renders.\n * This lets us apply optimizations like `React.memo` to minimize re-rendering screens.\n */\nexport default function useNavigationCache<\n State extends NavigationState,\n ScreenOptions extends {},\n EventMap extends Record<string, any>\n>({\n state,\n getState,\n navigation,\n setOptions,\n router,\n emitter,\n}: Options<State, EventMap>) {\n const { stackRef } = React.useContext(NavigationBuilderContext);\n\n // Cache object which holds navigation objects for each screen\n // We use `React.useMemo` instead of `React.useRef` coz we want to invalidate it when deps change\n // In reality, these deps will rarely change, if ever\n const cache = React.useMemo(\n () => ({ current: {} as NavigationCache<State, ScreenOptions, EventMap> }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [getState, navigation, setOptions, router, emitter]\n );\n\n const actions = {\n ...router.actionCreators,\n ...CommonActions,\n };\n\n cache.current = state.routes.reduce<\n NavigationCache<State, ScreenOptions, EventMap>\n >((acc, route) => {\n const previous = cache.current[route.key];\n\n type Thunk =\n | NavigationAction\n | ((state: State) => NavigationAction | null | undefined);\n\n if (previous) {\n // If a cached navigation object already exists, reuse it\n acc[route.key] = previous;\n } else {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { emit, ...rest } = navigation;\n\n const dispatch = (thunk: Thunk) => {\n const action = typeof thunk === 'function' ? thunk(getState()) : thunk;\n\n if (action != null) {\n navigation.dispatch({ source: route.key, ...action });\n }\n };\n\n const withStack = (callback: () => void) => {\n let isStackSet = false;\n\n try {\n if (\n process.env.NODE_ENV !== 'production' &&\n stackRef &&\n !stackRef.current\n ) {\n // Capture the stack trace for devtools\n stackRef.current = new Error().stack;\n isStackSet = true;\n }\n\n callback();\n } finally {\n if (isStackSet && stackRef) {\n stackRef.current = undefined;\n }\n }\n };\n\n const helpers = Object.keys(actions).reduce<Record<string, () => void>>(\n (acc, name) => {\n acc[name] = (...args: any) =>\n withStack(() =>\n // @ts-expect-error: name is a valid key, but TypeScript is dumb\n dispatch(actions[name](...args))\n );\n\n return acc;\n },\n {}\n );\n\n acc[route.key] = {\n ...rest,\n ...helpers,\n // FIXME: too much work to fix the types for now\n ...(emitter.create(route.key) as any),\n dispatch: (thunk: Thunk) => withStack(() => dispatch(thunk)),\n getParent: (id?: string) => {\n if (id !== undefined && id === rest.getId()) {\n // If the passed id is the same as the current navigation id,\n // we return the cached navigation object for the relevant route\n return acc[route.key];\n }\n\n return rest.getParent(id);\n },\n setOptions: (options: object) =>\n setOptions((o) => ({\n ...o,\n [route.key]: { ...o[route.key], ...options },\n })),\n isFocused: () => {\n const state = getState();\n\n if (state.routes[state.index].key !== route.key) {\n return false;\n }\n\n // If the current screen is focused, we also need to check if parent navigator is focused\n // This makes sure that we return the focus state in the whole tree, not just this navigator\n return navigation ? navigation.isFocused() : true;\n },\n };\n }\n\n return acc;\n }, {});\n\n return cache.current;\n}\n"],"mappings":"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"}
\No newline at end of file