@react-navigation/core 8.0.0-alpha.4 → 8.0.0-alpha.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -14
- package/lib/module/BaseNavigationContainer.js +173 -90
- package/lib/module/BaseNavigationContainer.js.map +1 -1
- package/lib/module/ConsumedParamsContext.js +5 -0
- package/lib/module/ConsumedParamsContext.js.map +1 -0
- package/lib/module/DataLoading.js +129 -0
- package/lib/module/DataLoading.js.map +1 -0
- package/lib/module/NavigationBuilderContext.js +7 -10
- package/lib/module/NavigationBuilderContext.js.map +1 -1
- package/lib/module/NavigationIndependentTree.js +54 -9
- package/lib/module/NavigationIndependentTree.js.map +1 -1
- package/lib/module/NavigationProvider.js +37 -12
- package/lib/module/NavigationProvider.js.map +1 -1
- package/lib/module/NavigationRootContext.js +8 -0
- package/lib/module/NavigationRootContext.js.map +1 -0
- package/lib/module/NavigationStateContext.js +3 -0
- package/lib/module/NavigationStateContext.js.map +1 -1
- package/lib/module/PreventRemoveContext.js.map +1 -1
- package/lib/module/PreventRemoveProvider.js +40 -31
- package/lib/module/PreventRemoveProvider.js.map +1 -1
- package/lib/module/SceneView.js +29 -57
- package/lib/module/SceneView.js.map +1 -1
- package/lib/module/StaticNavigation.js +219 -67
- package/lib/module/StaticNavigation.js.map +1 -1
- package/lib/module/StaticTreeContext.js +5 -0
- package/lib/module/StaticTreeContext.js.map +1 -0
- package/lib/module/createNavigationContainerRef.js +7 -9
- package/lib/module/createNavigationContainerRef.js.map +1 -1
- package/lib/module/createNavigatorFactory.js +27 -5
- package/lib/module/createNavigatorFactory.js.map +1 -1
- package/lib/module/findFocusedRoute.js +7 -4
- package/lib/module/findFocusedRoute.js.map +1 -1
- package/lib/module/getActionFromState.js +45 -20
- package/lib/module/getActionFromState.js.map +1 -1
- package/lib/module/getPathFromState.js +204 -94
- package/lib/module/getPathFromState.js.map +1 -1
- package/lib/module/getPatternParts.js +61 -14
- package/lib/module/getPatternParts.js.map +1 -1
- package/lib/module/getStateFromPath.js +608 -272
- package/lib/module/getStateFromPath.js.map +1 -1
- package/lib/module/getStateFromRouteParams.js +23 -0
- package/lib/module/getStateFromRouteParams.js.map +1 -0
- package/lib/module/index.js +7 -6
- package/lib/module/index.js.map +1 -1
- package/lib/module/internal.js +2 -0
- package/lib/module/internal.js.map +1 -0
- package/lib/module/isRecordEqual.js +1 -1
- package/lib/module/isRecordEqual.js.map +1 -1
- package/lib/module/queryString.js +71 -0
- package/lib/module/queryString.js.map +1 -0
- package/lib/module/theming/useTheme.js +1 -1
- package/lib/module/theming/useTheme.js.map +1 -1
- package/lib/module/types.js +35 -1
- package/lib/module/types.js.map +1 -1
- package/lib/module/useDescriptors.js +65 -25
- package/lib/module/useDescriptors.js.map +1 -1
- package/lib/module/useEventEmitter.js +48 -33
- package/lib/module/useEventEmitter.js.map +1 -1
- package/lib/module/useFocusEffect.js +4 -2
- package/lib/module/useFocusEffect.js.map +1 -1
- package/lib/module/useFocusEvents.js +15 -5
- package/lib/module/useFocusEvents.js.map +1 -1
- package/lib/module/useFocusedListenersChildrenAdapter.js +3 -3
- package/lib/module/useFocusedListenersChildrenAdapter.js.map +1 -1
- package/lib/module/useIsFocused.js +8 -12
- package/lib/module/useIsFocused.js.map +1 -1
- package/lib/module/useKeyedChildListeners.js +5 -2
- package/lib/module/useKeyedChildListeners.js.map +1 -1
- package/lib/module/useLazyValue.js.map +1 -1
- package/lib/module/useNavigation.js +4 -17
- package/lib/module/useNavigation.js.map +1 -1
- package/lib/module/useNavigationBuilder.js +244 -147
- package/lib/module/useNavigationBuilder.js.map +1 -1
- package/lib/module/useNavigationCache.js +92 -89
- package/lib/module/useNavigationCache.js.map +1 -1
- package/lib/module/useNavigationHelpers.js +22 -29
- package/lib/module/useNavigationHelpers.js.map +1 -1
- package/lib/module/useNavigationIndependentTree.js +1 -1
- package/lib/module/useNavigationIndependentTree.js.map +1 -1
- package/lib/module/useNavigationState.js +158 -46
- package/lib/module/useNavigationState.js.map +1 -1
- package/lib/module/useOnAction.js +58 -11
- package/lib/module/useOnAction.js.map +1 -1
- package/lib/module/useOnGetNavigation.js +26 -0
- package/lib/module/useOnGetNavigation.js.map +1 -0
- package/lib/module/useOnGetState.js +7 -4
- package/lib/module/useOnGetState.js.map +1 -1
- package/lib/module/useOnPreventRemove.js +40 -31
- package/lib/module/useOnPreventRemove.js.map +1 -1
- package/lib/module/useOnRouteFocus.js +2 -2
- package/lib/module/useOnRouteFocus.js.map +1 -1
- package/lib/module/useOptionsGetters.js +35 -27
- package/lib/module/useOptionsGetters.js.map +1 -1
- package/lib/module/usePreventRemove.js +11 -5
- package/lib/module/usePreventRemove.js.map +1 -1
- package/lib/module/usePreventRemoveContext.js +2 -2
- package/lib/module/usePreventRemoveContext.js.map +1 -1
- package/lib/module/useRegisterNavigator.js +3 -4
- package/lib/module/useRegisterNavigator.js.map +1 -1
- package/lib/module/useRoute.js +2 -0
- package/lib/module/useRoute.js.map +1 -1
- package/lib/module/useRouteCache.js +51 -35
- package/lib/module/useRouteCache.js.map +1 -1
- package/lib/module/useScheduleUpdate.js +12 -10
- package/lib/module/useScheduleUpdate.js.map +1 -1
- package/lib/module/useStateForPath.js +1 -1
- package/lib/module/useStateForPath.js.map +1 -1
- package/lib/module/useSyncState.js +37 -15
- package/lib/module/useSyncState.js.map +1 -1
- package/lib/module/validatePathConfig.js +50 -36
- package/lib/module/validatePathConfig.js.map +1 -1
- package/lib/typescript/src/BaseNavigationContainer.d.ts +6 -3
- package/lib/typescript/src/BaseNavigationContainer.d.ts.map +1 -1
- package/lib/typescript/src/ConsumedParamsContext.d.ts +3 -0
- package/lib/typescript/src/ConsumedParamsContext.d.ts.map +1 -0
- package/lib/typescript/src/DataLoading.d.ts +21 -0
- package/lib/typescript/src/DataLoading.d.ts.map +1 -0
- package/lib/typescript/src/EnsureSingleNavigator.d.ts +1 -1
- package/lib/typescript/src/EnsureSingleNavigator.d.ts.map +1 -1
- package/lib/typescript/src/Group.d.ts +1 -1
- package/lib/typescript/src/Group.d.ts.map +1 -1
- package/lib/typescript/src/NavigationBuilderContext.d.ts +22 -14
- package/lib/typescript/src/NavigationBuilderContext.d.ts.map +1 -1
- package/lib/typescript/src/NavigationContainerRefContext.d.ts +1 -1
- package/lib/typescript/src/NavigationContainerRefContext.d.ts.map +1 -1
- package/lib/typescript/src/NavigationFocusedRouteStateContext.d.ts +4 -4
- package/lib/typescript/src/NavigationFocusedRouteStateContext.d.ts.map +1 -1
- package/lib/typescript/src/NavigationHelpersContext.d.ts +1 -1
- package/lib/typescript/src/NavigationHelpersContext.d.ts.map +1 -1
- package/lib/typescript/src/NavigationIndependentTree.d.ts +1 -1
- package/lib/typescript/src/NavigationIndependentTree.d.ts.map +1 -1
- package/lib/typescript/src/NavigationProvider.d.ts +21 -18
- package/lib/typescript/src/NavigationProvider.d.ts.map +1 -1
- package/lib/typescript/src/NavigationRootContext.d.ts +8 -0
- package/lib/typescript/src/NavigationRootContext.d.ts.map +1 -0
- package/lib/typescript/src/NavigationStateContext.d.ts +3 -3
- package/lib/typescript/src/NavigationStateContext.d.ts.map +1 -1
- package/lib/typescript/src/PreventRemoveContext.d.ts +1 -0
- package/lib/typescript/src/PreventRemoveContext.d.ts.map +1 -1
- package/lib/typescript/src/PreventRemoveProvider.d.ts +1 -1
- package/lib/typescript/src/PreventRemoveProvider.d.ts.map +1 -1
- package/lib/typescript/src/SceneView.d.ts +5 -2
- package/lib/typescript/src/SceneView.d.ts.map +1 -1
- package/lib/typescript/src/Screen.d.ts +1 -1
- package/lib/typescript/src/Screen.d.ts.map +1 -1
- package/lib/typescript/src/StaticContainer.d.ts +1 -1
- package/lib/typescript/src/StaticContainer.d.ts.map +1 -1
- package/lib/typescript/src/StaticNavigation.d.ts +189 -111
- package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
- package/lib/typescript/src/StaticTreeContext.d.ts +4 -0
- package/lib/typescript/src/StaticTreeContext.d.ts.map +1 -0
- package/lib/typescript/src/createNavigationContainerRef.d.ts +1 -1
- package/lib/typescript/src/createNavigationContainerRef.d.ts.map +1 -1
- package/lib/typescript/src/createNavigatorFactory.d.ts +23 -5
- package/lib/typescript/src/createNavigatorFactory.d.ts.map +1 -1
- package/lib/typescript/src/findFocusedRoute.d.ts +3 -8
- package/lib/typescript/src/findFocusedRoute.d.ts.map +1 -1
- package/lib/typescript/src/getActionFromState.d.ts +4 -4
- package/lib/typescript/src/getActionFromState.d.ts.map +1 -1
- package/lib/typescript/src/getPathFromState.d.ts +3 -3
- package/lib/typescript/src/getPathFromState.d.ts.map +1 -1
- package/lib/typescript/src/getPatternParts.d.ts +5 -2
- package/lib/typescript/src/getPatternParts.d.ts.map +1 -1
- package/lib/typescript/src/getStateFromPath.d.ts +4 -7
- package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
- package/lib/typescript/src/getStateFromRouteParams.d.ts +3 -0
- package/lib/typescript/src/getStateFromRouteParams.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +36 -33
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/internal.d.ts +3 -0
- package/lib/typescript/src/internal.d.ts.map +1 -0
- package/lib/typescript/src/isRecordEqual.d.ts.map +1 -1
- package/lib/typescript/src/queryString.d.ts +5 -0
- package/lib/typescript/src/queryString.d.ts.map +1 -0
- package/lib/typescript/src/theming/ThemeContext.d.ts +1 -1
- package/lib/typescript/src/theming/ThemeContext.d.ts.map +1 -1
- package/lib/typescript/src/theming/ThemeProvider.d.ts +2 -2
- package/lib/typescript/src/theming/ThemeProvider.d.ts.map +1 -1
- package/lib/typescript/src/theming/useTheme.d.ts +1 -1
- package/lib/typescript/src/theming/useTheme.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +265 -167
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/useChildListeners.d.ts +3 -3
- package/lib/typescript/src/useChildListeners.d.ts.map +1 -1
- package/lib/typescript/src/useDescriptors.d.ts +13 -11
- package/lib/typescript/src/useDescriptors.d.ts.map +1 -1
- package/lib/typescript/src/useEventEmitter.d.ts +2 -2
- package/lib/typescript/src/useEventEmitter.d.ts.map +1 -1
- package/lib/typescript/src/useFocusEffect.d.ts.map +1 -1
- package/lib/typescript/src/useFocusEvents.d.ts +2 -2
- package/lib/typescript/src/useFocusEvents.d.ts.map +1 -1
- package/lib/typescript/src/useFocusedListenersChildrenAdapter.d.ts +2 -2
- package/lib/typescript/src/useFocusedListenersChildrenAdapter.d.ts.map +1 -1
- package/lib/typescript/src/useIsFocused.d.ts +4 -0
- package/lib/typescript/src/useIsFocused.d.ts.map +1 -1
- package/lib/typescript/src/useKeyedChildListeners.d.ts +4 -3
- package/lib/typescript/src/useKeyedChildListeners.d.ts.map +1 -1
- package/lib/typescript/src/useLazyValue.d.ts.map +1 -1
- package/lib/typescript/src/useNavigation.d.ts +4 -2
- package/lib/typescript/src/useNavigation.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationBuilder.d.ts +22 -63
- package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationCache.d.ts +6 -5
- package/lib/typescript/src/useNavigationCache.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationContainerRef.d.ts +1 -1
- package/lib/typescript/src/useNavigationContainerRef.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationHelpers.d.ts +18 -58
- package/lib/typescript/src/useNavigationHelpers.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationState.d.ts +19 -3
- package/lib/typescript/src/useNavigationState.d.ts.map +1 -1
- package/lib/typescript/src/useOnAction.d.ts +9 -9
- package/lib/typescript/src/useOnAction.d.ts.map +1 -1
- package/lib/typescript/src/useOnGetNavigation.d.ts +12 -0
- package/lib/typescript/src/useOnGetNavigation.d.ts.map +1 -0
- package/lib/typescript/src/useOnGetState.d.ts +1 -1
- package/lib/typescript/src/useOnGetState.d.ts.map +1 -1
- package/lib/typescript/src/useOnPreventRemove.d.ts +5 -9
- package/lib/typescript/src/useOnPreventRemove.d.ts.map +1 -1
- package/lib/typescript/src/useOnRouteFocus.d.ts +6 -6
- package/lib/typescript/src/useOnRouteFocus.d.ts.map +1 -1
- package/lib/typescript/src/useOptionsGetters.d.ts +4 -4
- package/lib/typescript/src/useOptionsGetters.d.ts.map +1 -1
- package/lib/typescript/src/usePreventRemove.d.ts.map +1 -1
- package/lib/typescript/src/usePreventRemoveContext.d.ts +2 -1
- package/lib/typescript/src/usePreventRemoveContext.d.ts.map +1 -1
- package/lib/typescript/src/useRegisterNavigator.d.ts.map +1 -1
- package/lib/typescript/src/useRoute.d.ts +7 -3
- package/lib/typescript/src/useRoute.d.ts.map +1 -1
- package/lib/typescript/src/useRouteCache.d.ts +7 -12
- package/lib/typescript/src/useRouteCache.d.ts.map +1 -1
- package/lib/typescript/src/useScheduleUpdate.d.ts +5 -4
- package/lib/typescript/src/useScheduleUpdate.d.ts.map +1 -1
- package/lib/typescript/src/useStateForPath.d.ts +1 -1
- package/lib/typescript/src/useStateForPath.d.ts.map +1 -1
- package/lib/typescript/src/useSyncState.d.ts +1 -0
- package/lib/typescript/src/useSyncState.d.ts.map +1 -1
- package/lib/typescript/src/utilities.d.ts +79 -39
- package/lib/typescript/src/utilities.d.ts.map +1 -1
- package/lib/typescript/src/validatePathConfig.d.ts.map +1 -1
- package/package.json +26 -22
- package/src/BaseNavigationContainer.tsx +459 -332
- package/src/ConsumedParamsContext.tsx +5 -0
- package/src/DataLoading.tsx +206 -0
- package/src/NavigationBuilderContext.tsx +44 -25
- package/src/NavigationFocusedRouteStateContext.tsx +4 -4
- package/src/NavigationIndependentTree.tsx +60 -12
- package/src/NavigationProvider.tsx +59 -21
- package/src/NavigationRootContext.tsx +11 -0
- package/src/NavigationStateContext.tsx +6 -6
- package/src/PreventRemoveContext.tsx +1 -0
- package/src/PreventRemoveProvider.tsx +55 -56
- package/src/SceneView.tsx +31 -57
- package/src/StaticNavigation.tsx +715 -328
- package/src/StaticTreeContext.tsx +7 -0
- package/src/createNavigationContainerRef.tsx +12 -11
- package/src/createNavigatorFactory.tsx +92 -8
- package/src/findFocusedRoute.tsx +16 -16
- package/src/getActionFromState.tsx +87 -51
- package/src/getPathFromState.tsx +310 -134
- package/src/getPatternParts.tsx +98 -16
- package/src/getStateFromPath.tsx +971 -344
- package/src/getStateFromRouteParams.tsx +59 -0
- package/src/index.tsx +57 -6
- package/src/internal.tsx +2 -0
- package/src/isRecordEqual.tsx +3 -1
- package/src/queryString.ts +109 -0
- package/src/theming/useTheme.tsx +1 -1
- package/src/types.tsx +799 -377
- package/src/useDescriptors.tsx +151 -43
- package/src/useEventEmitter.tsx +53 -39
- package/src/useFocusEffect.tsx +5 -2
- package/src/useFocusEvents.tsx +19 -8
- package/src/useFocusedListenersChildrenAdapter.tsx +3 -3
- package/src/useIsFocused.tsx +18 -21
- package/src/useKeyedChildListeners.tsx +5 -2
- package/src/useLazyValue.tsx +2 -2
- package/src/useNavigation.tsx +9 -26
- package/src/useNavigationBuilder.tsx +370 -201
- package/src/useNavigationCache.tsx +148 -123
- package/src/useNavigationHelpers.tsx +27 -37
- package/src/useNavigationIndependentTree.tsx +1 -1
- package/src/useNavigationState.tsx +207 -69
- package/src/useOnAction.tsx +92 -18
- package/src/useOnGetNavigation.tsx +30 -0
- package/src/useOnGetState.tsx +8 -4
- package/src/useOnPreventRemove.tsx +78 -43
- package/src/useOnRouteFocus.tsx +11 -15
- package/src/useOptionsGetters.tsx +44 -30
- package/src/usePreventRemove.tsx +13 -5
- package/src/usePreventRemoveContext.tsx +2 -2
- package/src/useRegisterNavigator.tsx +4 -4
- package/src/useRoute.tsx +20 -6
- package/src/useRouteCache.tsx +57 -35
- package/src/useScheduleUpdate.tsx +13 -11
- package/src/useStateForPath.tsx +1 -1
- package/src/useSyncState.tsx +39 -15
- package/src/utilities.tsx +151 -35
- package/src/validatePathConfig.tsx +86 -57
- package/lib/module/CurrentRenderContext.js +0 -10
- package/lib/module/CurrentRenderContext.js.map +0 -1
- package/lib/module/NavigationMetaContext.js +0 -15
- package/lib/module/NavigationMetaContext.js.map +0 -1
- package/lib/module/checkSerializable.js +0 -46
- package/lib/module/checkSerializable.js.map +0 -1
- package/lib/module/useComponent.js +0 -34
- package/lib/module/useComponent.js.map +0 -1
- package/lib/module/useCurrentRender.js +0 -19
- package/lib/module/useCurrentRender.js.map +0 -1
- package/lib/typescript/src/CurrentRenderContext.d.ts +0 -9
- package/lib/typescript/src/CurrentRenderContext.d.ts.map +0 -1
- package/lib/typescript/src/NavigationMetaContext.d.ts +0 -12
- package/lib/typescript/src/NavigationMetaContext.d.ts.map +0 -1
- package/lib/typescript/src/checkSerializable.d.ts +0 -10
- package/lib/typescript/src/checkSerializable.d.ts.map +0 -1
- package/lib/typescript/src/useComponent.d.ts +0 -7
- package/lib/typescript/src/useComponent.d.ts.map +0 -1
- package/lib/typescript/src/useCurrentRender.d.ts +0 -14
- package/lib/typescript/src/useCurrentRender.d.ts.map +0 -1
- package/src/CurrentRenderContext.tsx +0 -9
- package/src/NavigationMetaContext.tsx +0 -14
- package/src/checkSerializable.tsx +0 -74
- package/src/useComponent.tsx +0 -37
- package/src/useCurrentRender.tsx +0 -31
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
NavigationAction,
|
|
3
|
+
NavigationRoute,
|
|
3
4
|
NavigationState,
|
|
5
|
+
ParamListBase,
|
|
6
|
+
PartialRoute,
|
|
4
7
|
} from '@react-navigation/routers';
|
|
5
8
|
import * as React from 'react';
|
|
6
9
|
|
|
7
10
|
import {
|
|
8
11
|
type ChildBeforeRemoveListener,
|
|
9
|
-
|
|
12
|
+
useNavigationBuilderContext,
|
|
10
13
|
} from './NavigationBuilderContext';
|
|
11
14
|
import { NavigationRouteContext } from './NavigationProvider';
|
|
12
15
|
import type { EventMapCore } from './types';
|
|
@@ -23,50 +26,76 @@ const VISITED_ROUTE_KEYS = Symbol('VISITED_ROUTE_KEYS');
|
|
|
23
26
|
export const shouldPreventRemove = (
|
|
24
27
|
emitter: NavigationEventEmitter<EventMapCore<any>>,
|
|
25
28
|
beforeRemoveListeners: Record<string, ChildBeforeRemoveListener | undefined>,
|
|
26
|
-
currentRoutes:
|
|
27
|
-
nextRoutes:
|
|
29
|
+
currentRoutes: NavigationRoute<ParamListBase, string>[],
|
|
30
|
+
nextRoutes: (
|
|
31
|
+
| NavigationRoute<ParamListBase, string>
|
|
32
|
+
| PartialRoute<NavigationRoute<ParamListBase, string>>
|
|
33
|
+
)[],
|
|
28
34
|
action: NavigationAction
|
|
29
35
|
) => {
|
|
30
|
-
const
|
|
36
|
+
const nextRoutesByKey = new Map(
|
|
37
|
+
nextRoutes
|
|
38
|
+
.map((route) => [route.key, route] as const)
|
|
39
|
+
.filter(([, route]) => route.key != null)
|
|
40
|
+
);
|
|
31
41
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const visitedRouteKeys: Set<string> =
|
|
38
|
-
// @ts-expect-error: add this property to mark that we've already emitted this action
|
|
39
|
-
action[VISITED_ROUTE_KEYS] ?? new Set<string>();
|
|
42
|
+
const visitedRouteKeys =
|
|
43
|
+
VISITED_ROUTE_KEYS in action && action[VISITED_ROUTE_KEYS] instanceof Set
|
|
44
|
+
? action[VISITED_ROUTE_KEYS]
|
|
45
|
+
: new Set<string>();
|
|
40
46
|
|
|
41
47
|
const beforeRemoveAction = {
|
|
42
48
|
...action,
|
|
43
49
|
[VISITED_ROUTE_KEYS]: visitedRouteKeys,
|
|
44
50
|
};
|
|
45
51
|
|
|
46
|
-
|
|
52
|
+
// Call these in reverse order so last screens handle the event first
|
|
53
|
+
const reversedCurrentRoutes = [...currentRoutes].reverse();
|
|
54
|
+
|
|
55
|
+
for (const route of reversedCurrentRoutes) {
|
|
47
56
|
if (visitedRouteKeys.has(route.key)) {
|
|
48
57
|
// Skip if we've already emitted this action for this screen
|
|
49
58
|
continue;
|
|
50
59
|
}
|
|
51
60
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
61
|
+
if (!nextRoutesByKey.has(route.key)) {
|
|
62
|
+
// The route is not in next state, so it's being removed
|
|
63
|
+
// First, we need to check if any child screens want to prevent it
|
|
64
|
+
const isPrevented = beforeRemoveListeners[route.key]?.(
|
|
65
|
+
beforeRemoveAction,
|
|
66
|
+
undefined
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
if (isPrevented) {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
visitedRouteKeys.add(route.key);
|
|
74
|
+
|
|
75
|
+
const event = emitter.emit({
|
|
76
|
+
type: 'beforeRemove',
|
|
77
|
+
target: route.key,
|
|
78
|
+
data: { action: beforeRemoveAction },
|
|
79
|
+
canPreventDefault: true,
|
|
80
|
+
});
|
|
60
81
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
82
|
+
if (event.defaultPrevented) {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
} else {
|
|
86
|
+
// The route is kept but its nested state changed, so propagate the check into the nested navigator
|
|
87
|
+
const nextRoute = nextRoutesByKey.get(route.key);
|
|
88
|
+
|
|
89
|
+
if (route.state != null && route.state !== nextRoute?.state) {
|
|
90
|
+
const isPrevented = beforeRemoveListeners[route.key]?.(
|
|
91
|
+
beforeRemoveAction,
|
|
92
|
+
nextRoute?.state
|
|
93
|
+
);
|
|
67
94
|
|
|
68
|
-
|
|
69
|
-
|
|
95
|
+
if (isPrevented) {
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
70
99
|
}
|
|
71
100
|
}
|
|
72
101
|
|
|
@@ -78,23 +107,29 @@ export function useOnPreventRemove({
|
|
|
78
107
|
emitter,
|
|
79
108
|
beforeRemoveListeners,
|
|
80
109
|
}: Options) {
|
|
81
|
-
const { addKeyedListener } =
|
|
82
|
-
|
|
110
|
+
const { addKeyedListener } = useNavigationBuilderContext();
|
|
111
|
+
|
|
112
|
+
const route = React.use(NavigationRouteContext);
|
|
113
|
+
|
|
83
114
|
const routeKey = route?.key;
|
|
84
115
|
|
|
85
|
-
React.
|
|
116
|
+
React.useInsertionEffect(() => {
|
|
86
117
|
if (routeKey) {
|
|
87
|
-
return addKeyedListener?.(
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
118
|
+
return addKeyedListener?.(
|
|
119
|
+
'beforeRemove',
|
|
120
|
+
routeKey,
|
|
121
|
+
(action, nextState) => {
|
|
122
|
+
const state = getState();
|
|
123
|
+
|
|
124
|
+
return shouldPreventRemove(
|
|
125
|
+
emitter,
|
|
126
|
+
beforeRemoveListeners,
|
|
127
|
+
state.routes,
|
|
128
|
+
nextState?.routes ?? [],
|
|
129
|
+
action
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
);
|
|
98
133
|
}
|
|
99
134
|
}, [addKeyedListener, beforeRemoveListeners, emitter, getState, routeKey]);
|
|
100
135
|
}
|
package/src/useOnRouteFocus.tsx
CHANGED
|
@@ -5,13 +5,13 @@ import type {
|
|
|
5
5
|
} from '@react-navigation/routers';
|
|
6
6
|
import * as React from 'react';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { useNavigationBuilderContext } from './NavigationBuilderContext';
|
|
9
9
|
|
|
10
|
-
type Options<Action extends NavigationAction> = {
|
|
11
|
-
router: Router<
|
|
12
|
-
getState: () =>
|
|
13
|
-
setState: (state:
|
|
14
|
-
key?: string;
|
|
10
|
+
type Options<State extends NavigationState, Action extends NavigationAction> = {
|
|
11
|
+
router: Router<State, Action>;
|
|
12
|
+
getState: () => State;
|
|
13
|
+
setState: (state: State) => void;
|
|
14
|
+
key?: string | undefined;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
/**
|
|
@@ -19,15 +19,11 @@ type Options<Action extends NavigationAction> = {
|
|
|
19
19
|
* Focus action needs to be treated specially, coz when a nested route is focused,
|
|
20
20
|
* the parent navigators also needs to be focused.
|
|
21
21
|
*/
|
|
22
|
-
export function useOnRouteFocus<
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}: Options<Action>) {
|
|
28
|
-
const { onRouteFocus: onRouteFocusParent } = React.useContext(
|
|
29
|
-
NavigationBuilderContext
|
|
30
|
-
);
|
|
22
|
+
export function useOnRouteFocus<
|
|
23
|
+
State extends NavigationState,
|
|
24
|
+
Action extends NavigationAction,
|
|
25
|
+
>({ router, getState, key: sourceRouteKey, setState }: Options<State, Action>) {
|
|
26
|
+
const { onRouteFocus: onRouteFocusParent } = useNavigationBuilderContext();
|
|
31
27
|
|
|
32
28
|
return React.useCallback(
|
|
33
29
|
(key: string) => {
|
|
@@ -1,42 +1,41 @@
|
|
|
1
|
-
import type { ParamListBase } from '@react-navigation/routers';
|
|
2
1
|
import * as React from 'react';
|
|
3
2
|
|
|
4
3
|
import { NavigationBuilderContext } from './NavigationBuilderContext';
|
|
5
|
-
import {
|
|
6
|
-
|
|
4
|
+
import { IsFocusedContext } from './useIsFocused';
|
|
5
|
+
|
|
6
|
+
export const OptionsGetterContext = React.createContext<
|
|
7
|
+
((key: string, getter: () => object | undefined | null) => void) | undefined
|
|
8
|
+
>(undefined);
|
|
7
9
|
|
|
8
10
|
type Options = {
|
|
9
11
|
key?: string;
|
|
10
|
-
navigation?: NavigationProp<ParamListBase>;
|
|
11
12
|
options?: object | undefined;
|
|
13
|
+
getFocusedRouteKey?: () => string | undefined;
|
|
12
14
|
};
|
|
13
15
|
|
|
14
|
-
export function useOptionsGetters({
|
|
16
|
+
export function useOptionsGetters({
|
|
17
|
+
key,
|
|
18
|
+
options,
|
|
19
|
+
getFocusedRouteKey,
|
|
20
|
+
}: Options) {
|
|
21
|
+
const isFocused = React.use(IsFocusedContext) ?? true;
|
|
22
|
+
|
|
15
23
|
const optionsRef = React.useRef<object | undefined>(options);
|
|
16
24
|
const optionsGettersFromChildRef = React.useRef<
|
|
17
25
|
Record<string, () => object | undefined | null>
|
|
18
26
|
>({});
|
|
19
27
|
|
|
20
|
-
const
|
|
21
|
-
const { addOptionsGetter: parentAddOptionsGetter } = React.useContext(
|
|
22
|
-
NavigationStateContext
|
|
23
|
-
);
|
|
28
|
+
const onOptionsChange = React.use(NavigationBuilderContext)?.onOptionsChange;
|
|
24
29
|
|
|
25
|
-
const
|
|
26
|
-
const isFocused = navigation?.isFocused() ?? true;
|
|
27
|
-
const hasChildren = Object.keys(optionsGettersFromChildRef.current).length;
|
|
30
|
+
const parentAddOptionsGetter = React.use(OptionsGetterContext);
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
onOptionsChange(optionsRef.current ?? {});
|
|
31
|
-
}
|
|
32
|
-
}, [navigation, onOptionsChange]);
|
|
33
|
-
|
|
34
|
-
React.useEffect(() => {
|
|
32
|
+
React.useInsertionEffect(() => {
|
|
35
33
|
optionsRef.current = options;
|
|
36
|
-
|
|
34
|
+
}, [options]);
|
|
37
35
|
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
React.useEffect(() => {
|
|
37
|
+
onOptionsChange?.();
|
|
38
|
+
}, [isFocused, onOptionsChange, options]);
|
|
40
39
|
|
|
41
40
|
const getOptionsFromListener = React.useCallback(() => {
|
|
42
41
|
for (const key in optionsGettersFromChildRef.current) {
|
|
@@ -54,9 +53,11 @@ export function useOptionsGetters({ key, options, navigation }: Options) {
|
|
|
54
53
|
}, []);
|
|
55
54
|
|
|
56
55
|
const getCurrentOptions = React.useCallback(() => {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if
|
|
56
|
+
// We use focused route key from the navigator instead of `isFocused`
|
|
57
|
+
// Because `isFocused` may reflect the value the screen last rendered with,
|
|
58
|
+
// e.g. if `Activity` hides the screen before it rendered the new value,
|
|
59
|
+
// it updates at a lower priority, so it may be delayed.
|
|
60
|
+
if (key != null && getFocusedRouteKey?.() !== key) {
|
|
60
61
|
return null;
|
|
61
62
|
}
|
|
62
63
|
|
|
@@ -67,24 +68,37 @@ export function useOptionsGetters({ key, options, navigation }: Options) {
|
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
return optionsRef.current;
|
|
70
|
-
}, [
|
|
71
|
+
}, [key, getFocusedRouteKey, getOptionsFromListener]);
|
|
71
72
|
|
|
72
|
-
React.
|
|
73
|
-
|
|
73
|
+
React.useInsertionEffect(() => {
|
|
74
|
+
// We don't have a parent at the root
|
|
75
|
+
if (key != null) {
|
|
76
|
+
return parentAddOptionsGetter?.(key, getCurrentOptions);
|
|
77
|
+
}
|
|
74
78
|
}, [getCurrentOptions, parentAddOptionsGetter, key]);
|
|
75
79
|
|
|
76
80
|
const addOptionsGetter = React.useCallback(
|
|
77
81
|
(key: string, getter: () => object | undefined | null) => {
|
|
78
82
|
optionsGettersFromChildRef.current[key] = getter;
|
|
79
|
-
|
|
83
|
+
|
|
84
|
+
// Hidden screens may register without running their passive effects.
|
|
85
|
+
// Wait until the commit finishes before reporting their options.
|
|
86
|
+
if (onOptionsChange !== undefined) {
|
|
87
|
+
void Promise.resolve().then(onOptionsChange);
|
|
88
|
+
}
|
|
80
89
|
|
|
81
90
|
return () => {
|
|
82
91
|
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
83
92
|
delete optionsGettersFromChildRef.current[key];
|
|
84
|
-
|
|
93
|
+
|
|
94
|
+
// Other getters and the focused route may still change during cleanup.
|
|
95
|
+
// Wait until the commit finishes before reporting the remaining options.
|
|
96
|
+
if (onOptionsChange !== undefined) {
|
|
97
|
+
void Promise.resolve().then(onOptionsChange);
|
|
98
|
+
}
|
|
85
99
|
};
|
|
86
100
|
},
|
|
87
|
-
[
|
|
101
|
+
[onOptionsChange]
|
|
88
102
|
);
|
|
89
103
|
|
|
90
104
|
return {
|
package/src/usePreventRemove.tsx
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { NavigationAction } from '@react-navigation/routers';
|
|
2
|
-
import { nanoid } from 'nanoid/non-secure';
|
|
3
2
|
import * as React from 'react';
|
|
4
3
|
import useLatestCallback from 'use-latest-callback';
|
|
5
4
|
|
|
@@ -18,20 +17,29 @@ export function usePreventRemove(
|
|
|
18
17
|
preventRemove: boolean,
|
|
19
18
|
callback: (options: { data: { action: NavigationAction } }) => void
|
|
20
19
|
) {
|
|
21
|
-
const
|
|
20
|
+
const id = React.useId();
|
|
22
21
|
|
|
23
22
|
const navigation = useNavigation();
|
|
24
23
|
const { key: routeKey } = useRoute();
|
|
25
24
|
|
|
26
|
-
const { setPreventRemove } = usePreventRemoveContext();
|
|
25
|
+
const { setPreventRemove, notifyPreventRemove } = usePreventRemoveContext();
|
|
27
26
|
|
|
28
|
-
React.
|
|
27
|
+
React.useInsertionEffect(() => {
|
|
29
28
|
setPreventRemove(id, routeKey, preventRemove);
|
|
29
|
+
|
|
30
30
|
return () => {
|
|
31
31
|
setPreventRemove(id, routeKey, false);
|
|
32
32
|
};
|
|
33
33
|
}, [setPreventRemove, id, routeKey, preventRemove]);
|
|
34
34
|
|
|
35
|
+
React.useEffect(() => {
|
|
36
|
+
notifyPreventRemove();
|
|
37
|
+
|
|
38
|
+
return () => {
|
|
39
|
+
notifyPreventRemove();
|
|
40
|
+
};
|
|
41
|
+
}, [id, routeKey, preventRemove, notifyPreventRemove]);
|
|
42
|
+
|
|
35
43
|
const beforeRemoveListener = useLatestCallback<
|
|
36
44
|
EventListenerCallback<EventMapCore<any>, 'beforeRemove'>
|
|
37
45
|
>((e) => {
|
|
@@ -44,7 +52,7 @@ export function usePreventRemove(
|
|
|
44
52
|
callback({ data: e.data });
|
|
45
53
|
});
|
|
46
54
|
|
|
47
|
-
React.
|
|
55
|
+
React.useInsertionEffect(
|
|
48
56
|
() => navigation?.addListener('beforeRemove', beforeRemoveListener),
|
|
49
57
|
[navigation, beforeRemoveListener]
|
|
50
58
|
);
|
|
@@ -3,11 +3,11 @@ import * as React from 'react';
|
|
|
3
3
|
import { PreventRemoveContext } from './PreventRemoveContext';
|
|
4
4
|
|
|
5
5
|
export function usePreventRemoveContext() {
|
|
6
|
-
const value = React.
|
|
6
|
+
const value = React.use(PreventRemoveContext);
|
|
7
7
|
|
|
8
8
|
if (value == null) {
|
|
9
9
|
throw new Error(
|
|
10
|
-
"Couldn't find the prevent remove context.
|
|
10
|
+
"Couldn't find the prevent remove context. This is likely a bug in the navigator.\n\nIf you're using a custom navigator, make sure that the navigator content is wrapped by the 'render' function returned by 'useNavigationBuilder'."
|
|
11
11
|
);
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { nanoid } from 'nanoid/non-secure';
|
|
2
1
|
import * as React from 'react';
|
|
3
2
|
|
|
4
3
|
import { SingleNavigatorContext } from './EnsureSingleNavigator';
|
|
@@ -8,8 +7,9 @@ import { SingleNavigatorContext } from './EnsureSingleNavigator';
|
|
|
8
7
|
* This is used to prevent multiple navigators under a single container or screen.
|
|
9
8
|
*/
|
|
10
9
|
export function useRegisterNavigator() {
|
|
11
|
-
const
|
|
12
|
-
|
|
10
|
+
const key = React.useId();
|
|
11
|
+
|
|
12
|
+
const container = React.use(SingleNavigatorContext);
|
|
13
13
|
|
|
14
14
|
if (container === undefined) {
|
|
15
15
|
throw new Error(
|
|
@@ -17,7 +17,7 @@ export function useRegisterNavigator() {
|
|
|
17
17
|
);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
React.
|
|
20
|
+
React.useInsertionEffect(() => {
|
|
21
21
|
const { register, unregister } = container;
|
|
22
22
|
|
|
23
23
|
register(key);
|
package/src/useRoute.tsx
CHANGED
|
@@ -5,15 +5,26 @@ import {
|
|
|
5
5
|
NamedRouteContextListContext,
|
|
6
6
|
NavigationRouteContext,
|
|
7
7
|
} from './NavigationProvider';
|
|
8
|
-
import type {
|
|
8
|
+
import type {
|
|
9
|
+
NestedParamLists,
|
|
10
|
+
RootParamList,
|
|
11
|
+
RouteForName,
|
|
12
|
+
RouteProp,
|
|
13
|
+
} from './types';
|
|
14
|
+
import type { KeyOf } from './utilities';
|
|
9
15
|
|
|
10
16
|
/**
|
|
11
17
|
* Get all possible route names from a param list and its nested navigators.
|
|
18
|
+
* Recurses into the param lists directly instead of using `RouteForName`,
|
|
19
|
+
* So the route objects don't need to be built just to get the names.
|
|
12
20
|
*/
|
|
13
|
-
type AllRouteNames<ParamList extends {}> =
|
|
14
|
-
ParamList
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
type AllRouteNames<ParamList extends {}> =
|
|
22
|
+
| KeyOf<ParamList>
|
|
23
|
+
| AllNestedRouteNames<NestedParamLists<ParamList>>;
|
|
24
|
+
|
|
25
|
+
type AllNestedRouteNames<ParamLists> = ParamLists extends {}
|
|
26
|
+
? AllRouteNames<ParamLists>
|
|
27
|
+
: never;
|
|
17
28
|
|
|
18
29
|
/**
|
|
19
30
|
* Hook to access the route prop of the parent screen anywhere.
|
|
@@ -22,7 +33,10 @@ type AllRouteNames<ParamList extends {}> = RouteForName<
|
|
|
22
33
|
*/
|
|
23
34
|
export function useRoute<
|
|
24
35
|
const ParamList extends {} = RootParamList,
|
|
25
|
-
|
|
36
|
+
// The `& string` reduces the constraint to a plain union of names,
|
|
37
|
+
// so errors for invalid names list the valid names
|
|
38
|
+
const RouteName extends AllRouteNames<ParamList> & string =
|
|
39
|
+
AllRouteNames<ParamList> & string,
|
|
26
40
|
>(name: RouteName): RouteForName<ParamList, RouteName>;
|
|
27
41
|
export function useRoute<
|
|
28
42
|
const ParamList extends {} = RootParamList,
|
package/src/useRouteCache.tsx
CHANGED
|
@@ -4,8 +4,6 @@ import * as React from 'react';
|
|
|
4
4
|
import { isRecordEqual } from './isRecordEqual';
|
|
5
5
|
import type { RouteProp } from './types';
|
|
6
6
|
|
|
7
|
-
type RouteCache = Map<string, RouteProp<ParamListBase>>;
|
|
8
|
-
|
|
9
7
|
/**
|
|
10
8
|
* Utilities such as `getFocusedRouteNameFromRoute` need to access state.
|
|
11
9
|
* So we need a way to suppress the warning for those use cases.
|
|
@@ -13,6 +11,10 @@ type RouteCache = Map<string, RouteProp<ParamListBase>>;
|
|
|
13
11
|
*/
|
|
14
12
|
export const CHILD_STATE = Symbol('CHILD_STATE');
|
|
15
13
|
|
|
14
|
+
type CachedRoute = RouteProp<ParamListBase> & {
|
|
15
|
+
[CHILD_STATE]?: NavigationState;
|
|
16
|
+
};
|
|
17
|
+
|
|
16
18
|
/**
|
|
17
19
|
* Hook to cache route props for each screen in the navigator.
|
|
18
20
|
* This lets add warnings and modifications to the route object but keep references between renders.
|
|
@@ -21,47 +23,67 @@ export function useRouteCache<State extends NavigationState>(
|
|
|
21
23
|
routes: State['routes']
|
|
22
24
|
) {
|
|
23
25
|
// Cache object which holds route objects for each screen
|
|
24
|
-
const cache = React.useMemo(
|
|
26
|
+
const cache = React.useMemo(
|
|
27
|
+
() => ({ current: new Map<string, CachedRoute>() }),
|
|
28
|
+
[]
|
|
29
|
+
);
|
|
25
30
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
const next = React.useMemo(() => {
|
|
32
|
+
return routes.reduce((acc, route) => {
|
|
33
|
+
const previous = cache.current.get(route.key);
|
|
29
34
|
|
|
30
|
-
|
|
35
|
+
const { state: _, ...routeWithoutState } = route;
|
|
31
36
|
|
|
32
|
-
|
|
33
|
-
// If a cached route object already exists, reuse it
|
|
34
|
-
proxy = previous;
|
|
35
|
-
} else {
|
|
36
|
-
proxy = routeWithoutState;
|
|
37
|
-
}
|
|
37
|
+
let proxy: CachedRoute;
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const value = proxy[key];
|
|
39
|
+
if (previous && isRecordEqual(previous, routeWithoutState)) {
|
|
40
|
+
// If a cached route object already exists, reuse it
|
|
41
|
+
proxy = previous;
|
|
42
|
+
} else {
|
|
43
|
+
proxy = routeWithoutState;
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
value
|
|
51
|
-
|
|
45
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
46
|
+
// FIXME: since the state is updated with mutation, the route object cannot be frozen
|
|
47
|
+
// As a workaround, loop through the object and make the properties readonly
|
|
48
|
+
// Only needed once per proxy - skip if we're reusing a previously-frozen one
|
|
49
|
+
for (const [key, value] of Object.entries(proxy)) {
|
|
50
|
+
Object.defineProperty(proxy, key, {
|
|
51
|
+
enumerable: true,
|
|
52
|
+
configurable: true,
|
|
53
|
+
writable: false,
|
|
54
|
+
value,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
52
58
|
}
|
|
53
|
-
}
|
|
54
59
|
|
|
55
|
-
|
|
56
|
-
enumerable: false,
|
|
57
|
-
configurable: true,
|
|
58
|
-
value: state,
|
|
59
|
-
});
|
|
60
|
+
acc.set(route.key, proxy);
|
|
60
61
|
|
|
61
|
-
|
|
62
|
+
return acc;
|
|
63
|
+
}, new Map<string, CachedRoute>());
|
|
64
|
+
}, [cache, routes]);
|
|
62
65
|
|
|
63
|
-
|
|
64
|
-
|
|
66
|
+
React.useInsertionEffect(() => {
|
|
67
|
+
cache.current = next;
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Update child state on every render, including when the memo is reused.
|
|
71
|
+
// This restores the previous child state when a pending render is canceled.
|
|
72
|
+
return Array.from(next.values(), (proxy, index) => {
|
|
73
|
+
const state = routes[index]?.state;
|
|
74
|
+
|
|
75
|
+
// FIXME: We mutate the child state without replacing the cached route object,
|
|
76
|
+
// so nested navigation doesn't re-render the parent screen.
|
|
77
|
+
// This is not concurrent render safe, pending renders mutate this shared child state.
|
|
78
|
+
// Then `getFocusedRouteNameFromRoute` can expose it before the render commits.
|
|
79
|
+
if (proxy[CHILD_STATE] !== state) {
|
|
80
|
+
Object.defineProperty(proxy, CHILD_STATE, {
|
|
81
|
+
enumerable: false,
|
|
82
|
+
configurable: true,
|
|
83
|
+
value: state,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
65
86
|
|
|
66
|
-
|
|
87
|
+
return proxy;
|
|
88
|
+
});
|
|
67
89
|
}
|
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import useLatestCallback from 'use-latest-callback';
|
|
2
3
|
|
|
3
|
-
import {
|
|
4
|
+
import { useNavigationBuilderContext } from './NavigationBuilderContext';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* When screen config changes, we want to update the navigator in the same update phase.
|
|
7
|
-
* However, navigation state is in the root component and React won't let us update it from a child.
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* However, navigation state is in the root component and React won't let us update it from a child during render.
|
|
9
|
+
* The render could also be interrupted in concurrent mode, so we need to update after commit.
|
|
10
|
+
* So we queue the update in an insertion effect and flush it in a layout effect.
|
|
11
|
+
* Insertion effects run before layout effects, so every navigator in the tree has queued its update before we flush.
|
|
12
|
+
* This lets nested updates be applied from the root down without clobbering each other.
|
|
11
13
|
*/
|
|
12
14
|
export function useScheduleUpdate(callback: () => void) {
|
|
13
|
-
const { scheduleUpdate, flushUpdates } =
|
|
14
|
-
NavigationBuilderContext
|
|
15
|
-
);
|
|
15
|
+
const { scheduleUpdate, flushUpdates } = useNavigationBuilderContext();
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
const latestCallback = useLatestCallback(callback);
|
|
18
|
+
|
|
19
|
+
React.useInsertionEffect(() => {
|
|
20
|
+
scheduleUpdate(latestCallback);
|
|
21
|
+
});
|
|
20
22
|
|
|
21
23
|
React.useLayoutEffect(flushUpdates);
|
|
22
24
|
}
|
package/src/useStateForPath.tsx
CHANGED
|
@@ -9,7 +9,7 @@ import { NavigationFocusedRouteStateContext } from './NavigationFocusedRouteStat
|
|
|
9
9
|
* @returns Minimal state to build a path for the current route.
|
|
10
10
|
*/
|
|
11
11
|
export function useStateForPath() {
|
|
12
|
-
const state = React.
|
|
12
|
+
const state = React.use(NavigationFocusedRouteStateContext);
|
|
13
13
|
|
|
14
14
|
return state;
|
|
15
15
|
}
|