@react-navigation/core 8.0.0-alpha.3 → 8.0.0-alpha.31
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/lib/module/BaseNavigationContainer.js +38 -19
- 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 +127 -0
- package/lib/module/DataLoading.js.map +1 -0
- package/lib/module/NavigationBuilderContext.js +1 -0
- package/lib/module/NavigationBuilderContext.js.map +1 -1
- package/lib/module/NavigationIndependentTree.js +20 -8
- package/lib/module/NavigationIndependentTree.js.map +1 -1
- package/lib/module/NavigationProvider.js +22 -11
- package/lib/module/NavigationProvider.js.map +1 -1
- 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 +37 -27
- package/lib/module/PreventRemoveProvider.js.map +1 -1
- package/lib/module/SceneView.js +10 -41
- package/lib/module/SceneView.js.map +1 -1
- package/lib/module/StaticNavigation.js +179 -50
- 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/checkSerializable.js +18 -13
- package/lib/module/checkSerializable.js.map +1 -1
- package/lib/module/createNavigationContainerRef.js +6 -8
- 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 +171 -90
- package/lib/module/getPathFromState.js.map +1 -1
- package/lib/module/getPatternParts.js +20 -4
- package/lib/module/getPatternParts.js.map +1 -1
- package/lib/module/getStateFromPath.js +487 -217
- 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 +5 -4
- package/lib/module/index.js.map +1 -1
- package/lib/module/theming/useTheme.js +1 -1
- package/lib/module/theming/useTheme.js.map +1 -1
- package/lib/module/types.js +35 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/useDescriptors.js +21 -11
- 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/useFocusEvents.js +12 -4
- package/lib/module/useFocusEvents.js.map +1 -1
- package/lib/module/useFocusedListenersChildrenAdapter.js +2 -2
- package/lib/module/useFocusedListenersChildrenAdapter.js.map +1 -1
- package/lib/module/useIsFocused.js +7 -12
- package/lib/module/useIsFocused.js.map +1 -1
- package/lib/module/useKeyedChildListeners.js +4 -2
- package/lib/module/useKeyedChildListeners.js.map +1 -1
- package/lib/module/useLazyValue.js.map +1 -1
- package/lib/module/useNavigation.js +2 -15
- package/lib/module/useNavigation.js.map +1 -1
- package/lib/module/useNavigationBuilder.js +204 -131
- package/lib/module/useNavigationBuilder.js.map +1 -1
- package/lib/module/useNavigationCache.js +22 -17
- package/lib/module/useNavigationCache.js.map +1 -1
- package/lib/module/useNavigationHelpers.js +28 -10
- 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 +125 -45
- package/lib/module/useNavigationState.js.map +1 -1
- package/lib/module/useOnAction.js +37 -7
- package/lib/module/useOnAction.js.map +1 -1
- package/lib/module/useOnGetState.js +6 -3
- package/lib/module/useOnGetState.js.map +1 -1
- package/lib/module/useOnPreventRemove.js +39 -30
- package/lib/module/useOnPreventRemove.js.map +1 -1
- package/lib/module/useOnRouteFocus.js +1 -1
- package/lib/module/useOnRouteFocus.js.map +1 -1
- package/lib/module/useOptionsGetters.js +10 -5
- package/lib/module/useOptionsGetters.js.map +1 -1
- package/lib/module/usePreventRemove.js +10 -3
- package/lib/module/usePreventRemove.js.map +1 -1
- package/lib/module/usePreventRemoveContext.js +1 -1
- package/lib/module/usePreventRemoveContext.js.map +1 -1
- package/lib/module/useRegisterNavigator.js +2 -2
- 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 +17 -11
- package/lib/module/useRouteCache.js.map +1 -1
- package/lib/module/useScheduleUpdate.js +9 -9
- 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 +32 -9
- 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 +9 -8
- 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 +12 -13
- package/lib/typescript/src/NavigationProvider.d.ts.map +1 -1
- package/lib/typescript/src/NavigationStateContext.d.ts +4 -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 +4 -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 -109
- 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/checkSerializable.d.ts +8 -4
- package/lib/typescript/src/checkSerializable.d.ts.map +1 -1
- 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 +1 -0
- 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/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 +260 -159
- 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/useComponent.d.ts +1 -1
- package/lib/typescript/src/useComponent.d.ts.map +1 -1
- package/lib/typescript/src/useDescriptors.d.ts +10 -9
- 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/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 +3 -0
- package/lib/typescript/src/useIsFocused.d.ts.map +1 -1
- package/lib/typescript/src/useKeyedChildListeners.d.ts +3 -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 +23 -30
- package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationCache.d.ts +3 -3
- 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 +19 -27
- package/lib/typescript/src/useNavigationHelpers.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationState.d.ts +17 -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/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 +1 -1
- 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/useRoute.d.ts +7 -3
- package/lib/typescript/src/useRoute.d.ts.map +1 -1
- package/lib/typescript/src/useRouteCache.d.ts +5 -5
- 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 +74 -37
- package/lib/typescript/src/utilities.d.ts.map +1 -1
- package/lib/typescript/src/validatePathConfig.d.ts.map +1 -1
- package/package.json +23 -22
- package/src/BaseNavigationContainer.tsx +362 -334
- package/src/ConsumedParamsContext.tsx +5 -0
- package/src/DataLoading.tsx +203 -0
- package/src/NavigationBuilderContext.tsx +14 -9
- package/src/NavigationFocusedRouteStateContext.tsx +4 -4
- package/src/NavigationIndependentTree.tsx +23 -12
- package/src/NavigationProvider.tsx +26 -15
- package/src/NavigationStateContext.tsx +9 -6
- package/src/PreventRemoveContext.tsx +1 -0
- package/src/PreventRemoveProvider.tsx +51 -46
- package/src/SceneView.tsx +11 -39
- package/src/StaticNavigation.tsx +659 -307
- package/src/StaticTreeContext.tsx +7 -0
- package/src/checkSerializable.tsx +35 -19
- package/src/createNavigationContainerRef.tsx +12 -9
- package/src/createNavigatorFactory.tsx +92 -8
- package/src/findFocusedRoute.tsx +16 -16
- package/src/getActionFromState.tsx +87 -51
- package/src/getPathFromState.tsx +254 -128
- package/src/getPatternParts.tsx +25 -4
- package/src/getStateFromPath.tsx +821 -331
- package/src/getStateFromRouteParams.tsx +59 -0
- package/src/index.tsx +55 -5
- package/src/theming/useTheme.tsx +1 -1
- package/src/types.tsx +798 -373
- package/src/useDescriptors.tsx +31 -14
- package/src/useEventEmitter.tsx +52 -38
- package/src/useFocusEvents.tsx +15 -7
- package/src/useFocusedListenersChildrenAdapter.tsx +2 -2
- package/src/useIsFocused.tsx +14 -21
- package/src/useKeyedChildListeners.tsx +4 -2
- package/src/useLazyValue.tsx +2 -2
- package/src/useNavigation.tsx +7 -24
- package/src/useNavigationBuilder.tsx +314 -186
- package/src/useNavigationCache.tsx +32 -25
- package/src/useNavigationHelpers.tsx +27 -10
- package/src/useNavigationIndependentTree.tsx +1 -1
- package/src/useNavigationState.tsx +168 -69
- package/src/useOnAction.tsx +61 -13
- package/src/useOnGetState.tsx +5 -3
- package/src/useOnPreventRemove.tsx +75 -42
- package/src/useOnRouteFocus.tsx +10 -12
- package/src/useOptionsGetters.tsx +11 -5
- package/src/usePreventRemove.tsx +12 -3
- package/src/usePreventRemoveContext.tsx +1 -1
- package/src/useRegisterNavigator.tsx +2 -2
- package/src/useRoute.tsx +20 -6
- package/src/useRouteCache.tsx +22 -16
- package/src/useScheduleUpdate.tsx +9 -10
- package/src/useStateForPath.tsx +1 -1
- package/src/useSyncState.tsx +35 -9
- package/src/utilities.tsx +144 -31
- package/src/validatePathConfig.tsx +86 -57
- package/lib/module/CurrentRenderContext.js +0 -10
- package/lib/module/CurrentRenderContext.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/useCurrentRender.d.ts +0 -14
- package/lib/typescript/src/useCurrentRender.d.ts.map +0 -1
- package/src/CurrentRenderContext.tsx +0 -9
- package/src/useCurrentRender.tsx +0 -31
|
@@ -23,8 +23,8 @@ type Options<
|
|
|
23
23
|
Partial<NavigationProp<ParamListBase, string, any, any, any>>;
|
|
24
24
|
setOptions: (
|
|
25
25
|
cb: (
|
|
26
|
-
options: Record<string, ScreenOptions>
|
|
27
|
-
) => Record<string, ScreenOptions>
|
|
26
|
+
options: Record<string, Partial<ScreenOptions> | undefined>
|
|
27
|
+
) => Record<string, Partial<ScreenOptions> | undefined>
|
|
28
28
|
) => void;
|
|
29
29
|
router: Router<State, NavigationAction>;
|
|
30
30
|
emitter: NavigationEventEmitter<EventMap>;
|
|
@@ -72,8 +72,8 @@ export function useNavigationCache<
|
|
|
72
72
|
router,
|
|
73
73
|
emitter,
|
|
74
74
|
}: Options<State, ScreenOptions, EventMap>) {
|
|
75
|
-
const parentNavigationHelpers = React.
|
|
76
|
-
const { stackRef } = React.
|
|
75
|
+
const parentNavigationHelpers = React.use(NavigationContext);
|
|
76
|
+
const { stackRef } = React.use(NavigationBuilderContext);
|
|
77
77
|
|
|
78
78
|
// Cache object which holds navigation objects for each screen
|
|
79
79
|
// We use `React.useMemo` instead of `React.useRef` coz we want to invalidate it when deps change
|
|
@@ -91,27 +91,15 @@ export function useNavigationCache<
|
|
|
91
91
|
[getState, parentNavigationHelpers, navigation, setOptions, emitter]
|
|
92
92
|
);
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
const next = routes.reduce<
|
|
95
95
|
NavigationCache<State, ScreenOptions, EventMap, ActionHelpers>
|
|
96
96
|
>((acc, route) => {
|
|
97
97
|
const previous = cache.current[route.key];
|
|
98
98
|
|
|
99
|
-
type Thunk =
|
|
100
|
-
| NavigationAction
|
|
101
|
-
| ((state: State) => NavigationAction | null | undefined);
|
|
102
|
-
|
|
103
99
|
if (previous) {
|
|
104
100
|
// If a cached navigation object already exists, reuse it
|
|
105
101
|
acc[route.key] = previous;
|
|
106
102
|
} else {
|
|
107
|
-
const dispatch = (thunk: Thunk) => {
|
|
108
|
-
const action = typeof thunk === 'function' ? thunk(getState()) : thunk;
|
|
109
|
-
|
|
110
|
-
if (action != null) {
|
|
111
|
-
navigation.dispatch({ source: route.key, ...action });
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
|
|
115
103
|
const withStack = (callback: () => void) => {
|
|
116
104
|
let isStackSet = false;
|
|
117
105
|
|
|
@@ -134,6 +122,23 @@ export function useNavigationCache<
|
|
|
134
122
|
}
|
|
135
123
|
};
|
|
136
124
|
|
|
125
|
+
const dispatch = (
|
|
126
|
+
thunk:
|
|
127
|
+
| NavigationAction
|
|
128
|
+
| ((state: State) => NavigationAction | null | undefined)
|
|
129
|
+
) => {
|
|
130
|
+
withStack(() =>
|
|
131
|
+
React.startTransition(() => {
|
|
132
|
+
const action =
|
|
133
|
+
typeof thunk === 'function' ? thunk(getState()) : thunk;
|
|
134
|
+
|
|
135
|
+
if (action != null) {
|
|
136
|
+
navigation.dispatch({ source: route.key, ...action });
|
|
137
|
+
}
|
|
138
|
+
})
|
|
139
|
+
);
|
|
140
|
+
};
|
|
141
|
+
|
|
137
142
|
const actions = {
|
|
138
143
|
...router.actionCreators,
|
|
139
144
|
...CommonActions,
|
|
@@ -142,10 +147,8 @@ export function useNavigationCache<
|
|
|
142
147
|
const helpers = Object.keys(actions).reduce<Record<string, () => void>>(
|
|
143
148
|
(acc, name) => {
|
|
144
149
|
acc[name] = (...args: any) =>
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
dispatch(actions[name](...args))
|
|
148
|
-
);
|
|
150
|
+
// @ts-expect-error: name is a valid key, but TypeScript is dumb
|
|
151
|
+
dispatch(actions[name](...args));
|
|
149
152
|
|
|
150
153
|
return acc;
|
|
151
154
|
},
|
|
@@ -160,7 +163,7 @@ export function useNavigationCache<
|
|
|
160
163
|
...helpers,
|
|
161
164
|
// FIXME: too much work to fix the types for now
|
|
162
165
|
...(emitter.create(route.key) as any),
|
|
163
|
-
dispatch
|
|
166
|
+
dispatch,
|
|
164
167
|
getParent: (routeName) => {
|
|
165
168
|
if (routeName === route.name) {
|
|
166
169
|
// If the passed route name is the same as the current route's name,
|
|
@@ -174,7 +177,7 @@ export function useNavigationCache<
|
|
|
174
177
|
|
|
175
178
|
return parentNavigationHelpers;
|
|
176
179
|
},
|
|
177
|
-
setOptions: (options:
|
|
180
|
+
setOptions: (options: Partial<ScreenOptions>) => {
|
|
178
181
|
setOptions((o) => ({
|
|
179
182
|
...o,
|
|
180
183
|
[route.key]: { ...o[route.key], ...options },
|
|
@@ -183,7 +186,7 @@ export function useNavigationCache<
|
|
|
183
186
|
isFocused: () => {
|
|
184
187
|
const state = rest.getState();
|
|
185
188
|
|
|
186
|
-
if (state.routes[state.index]
|
|
189
|
+
if (state.routes[state.index]?.key !== route.key) {
|
|
187
190
|
return false;
|
|
188
191
|
}
|
|
189
192
|
|
|
@@ -197,5 +200,9 @@ export function useNavigationCache<
|
|
|
197
200
|
return acc;
|
|
198
201
|
}, {});
|
|
199
202
|
|
|
200
|
-
|
|
203
|
+
React.useInsertionEffect(() => {
|
|
204
|
+
cache.current = next;
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
return next;
|
|
201
208
|
}
|
|
@@ -19,9 +19,9 @@ type Options<State extends NavigationState, Action extends NavigationAction> = {
|
|
|
19
19
|
onAction: (action: NavigationAction) => boolean;
|
|
20
20
|
onUnhandledAction: (action: NavigationAction) => void;
|
|
21
21
|
getState: () => State;
|
|
22
|
+
state: State;
|
|
22
23
|
emitter: NavigationEventEmitter<any>;
|
|
23
24
|
router: Router<State, Action>;
|
|
24
|
-
stateRef: React.RefObject<State | null>;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
/**
|
|
@@ -37,11 +37,28 @@ export function useNavigationHelpers<
|
|
|
37
37
|
onAction,
|
|
38
38
|
onUnhandledAction,
|
|
39
39
|
getState,
|
|
40
|
+
state,
|
|
40
41
|
emitter,
|
|
41
42
|
router,
|
|
42
|
-
stateRef,
|
|
43
43
|
}: Options<State, Action>) {
|
|
44
|
-
const parentNavigationHelpers = React.
|
|
44
|
+
const parentNavigationHelpers = React.use(NavigationContext);
|
|
45
|
+
|
|
46
|
+
// In some cases (e.g. route names change), internal state might have changed
|
|
47
|
+
// But it hasn't been committed yet, so hasn't propagated to any listeners
|
|
48
|
+
// During this time, we need to return the internal state in `getState`
|
|
49
|
+
// Otherwise it can return an inconsistent state during render in children
|
|
50
|
+
// This may affect hooks like `useNavigationState` that need to read the state during render
|
|
51
|
+
// To avoid this, we use a ref for render phase, and immediately clear it on commit
|
|
52
|
+
// The ref won't be cleared if the render is discarded, e.g. when interrupted
|
|
53
|
+
// So we also track the stored state the render was based on
|
|
54
|
+
// Then ignore the ref once the stored state changes due to another dispatch
|
|
55
|
+
const stateRef = React.useRef<{ state: State; base: State } | null>(null);
|
|
56
|
+
|
|
57
|
+
stateRef.current = { state, base: getState() };
|
|
58
|
+
|
|
59
|
+
React.useInsertionEffect(() => {
|
|
60
|
+
stateRef.current = null;
|
|
61
|
+
});
|
|
45
62
|
|
|
46
63
|
return React.useMemo(() => {
|
|
47
64
|
const dispatch = (op: Action | ((state: State) => Action)) => {
|
|
@@ -87,16 +104,16 @@ export function useNavigationHelpers<
|
|
|
87
104
|
);
|
|
88
105
|
},
|
|
89
106
|
getState: (): State => {
|
|
107
|
+
const current = getState();
|
|
108
|
+
const pending = stateRef.current;
|
|
109
|
+
|
|
90
110
|
// FIXME: Workaround for when the state is read during render
|
|
91
|
-
//
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
// Apart from `useSyncExternalStore`, `getState` should never be called during render
|
|
95
|
-
if (stateRef.current != null) {
|
|
96
|
-
return stateRef.current;
|
|
111
|
+
// Apart from subscriptions, `getState` should never be called during render
|
|
112
|
+
if (pending != null && pending.base === current) {
|
|
113
|
+
return pending.state;
|
|
97
114
|
}
|
|
98
115
|
|
|
99
|
-
return
|
|
116
|
+
return current;
|
|
100
117
|
},
|
|
101
118
|
} as NavigationHelpers<ParamListBase, EventMap> & ActionHelpers;
|
|
102
119
|
|
|
@@ -3,5 +3,5 @@ import * as React from 'react';
|
|
|
3
3
|
import { NavigationIndependentTreeContext } from './NavigationIndependentTreeContext';
|
|
4
4
|
|
|
5
5
|
export function useNavigationIndependentTree() {
|
|
6
|
-
return React.
|
|
6
|
+
return React.use(NavigationIndependentTreeContext);
|
|
7
7
|
}
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import type { NavigationState, ParamListBase } from '@react-navigation/routers';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import useLatestCallback from 'use-latest-callback';
|
|
4
|
-
import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector';
|
|
5
3
|
|
|
6
|
-
import type {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
RootNavigator,
|
|
10
|
-
} from './types';
|
|
11
|
-
import { useNavigation } from './useNavigation';
|
|
4
|
+
import type { NavigationListForNested, RootNavigator } from './types';
|
|
5
|
+
|
|
6
|
+
type NavigationStateEvent = 'update' | 'commit';
|
|
12
7
|
|
|
13
8
|
type NavigationStateListener = {
|
|
14
9
|
getState: () => NavigationState<ParamListBase>;
|
|
15
|
-
|
|
10
|
+
getSnapshot: () => NavigationState<ParamListBase>;
|
|
11
|
+
subscribe: (callback: (event: NavigationStateEvent) => void) => () => void;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type NavigationStateEntry = {
|
|
15
|
+
listener: NavigationStateListener;
|
|
16
|
+
state: NavigationState<ParamListBase>;
|
|
16
17
|
};
|
|
17
18
|
|
|
18
19
|
type NavigationStateForNested<
|
|
@@ -35,8 +36,8 @@ type NavigationStateForNested<
|
|
|
35
36
|
export function useNavigationState<
|
|
36
37
|
const T,
|
|
37
38
|
const Navigator = RootNavigator,
|
|
38
|
-
const RouteName extends
|
|
39
|
-
keyof NavigationListForNested<Navigator
|
|
39
|
+
const RouteName extends keyof NavigationListForNested<Navigator> =
|
|
40
|
+
keyof NavigationListForNested<Navigator>,
|
|
40
41
|
>(
|
|
41
42
|
routeName: RouteName,
|
|
42
43
|
selector: (state: NavigationStateForNested<Navigator, RouteName>) => T
|
|
@@ -45,99 +46,161 @@ export function useNavigationState<T>(
|
|
|
45
46
|
selector: (state: NavigationState<ParamListBase>) => T
|
|
46
47
|
): T;
|
|
47
48
|
export function useNavigationState(...args: unknown[]): unknown {
|
|
48
|
-
|
|
49
|
-
stateListener: NavigationStateListener | undefined,
|
|
50
|
-
selector;
|
|
49
|
+
const selector = typeof args[0] === 'string' ? args[1] : args[0];
|
|
51
50
|
|
|
52
|
-
if (typeof
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
navigation = useNavigation(args[0]);
|
|
57
|
-
selector = args[1];
|
|
58
|
-
} else {
|
|
59
|
-
selector = args[0];
|
|
51
|
+
if (typeof selector !== 'function') {
|
|
52
|
+
throw new Error(
|
|
53
|
+
`A selector function must be provided (got ${typeof selector}).`
|
|
54
|
+
);
|
|
60
55
|
}
|
|
61
56
|
|
|
62
|
-
|
|
63
|
-
|
|
57
|
+
// @ts-expect-error: the public overloads guarantee the selector's type, but
|
|
58
|
+
// the `unknown[]` implementation signature can't express it
|
|
59
|
+
const select: (state: NavigationState<ParamListBase>) => unknown = selector;
|
|
60
|
+
|
|
61
|
+
let listener: NavigationStateListener | undefined;
|
|
62
|
+
|
|
63
|
+
if (typeof args[0] === 'string') {
|
|
64
|
+
const name = args[0];
|
|
65
|
+
const listeners = React.use(NamedNavigationStateListenerListContext);
|
|
64
66
|
|
|
65
|
-
|
|
67
|
+
listener = listeners?.[name];
|
|
68
|
+
|
|
69
|
+
if (listener == null) {
|
|
70
|
+
throw new Error(
|
|
71
|
+
`Couldn't find a navigator for the route '${name}' in any of the parent screens. Is your component inside the correct screen?`
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
listener = React.use(NavigationStateListenerContext);
|
|
76
|
+
|
|
77
|
+
if (listener == null) {
|
|
66
78
|
throw new Error(
|
|
67
79
|
"Couldn't get the navigation state. Is your component inside a navigator?"
|
|
68
80
|
);
|
|
69
81
|
}
|
|
70
82
|
}
|
|
71
83
|
|
|
72
|
-
const subscribe =
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
84
|
+
const { getState, getSnapshot, subscribe } = listener;
|
|
85
|
+
|
|
86
|
+
// The store can contain state from a transition that hasn't committed yet.
|
|
87
|
+
// Reading it during render can show state that doesn't match the navigator in that render.
|
|
88
|
+
// The reducer lets React process state in the same render lane as the navigator.
|
|
89
|
+
const [entry, dispatch] = React.useReducer(
|
|
90
|
+
(previous: NavigationStateEntry, event: NavigationStateEvent) => {
|
|
91
|
+
// Navigation state can change between the dispatch and the reducer running.
|
|
92
|
+
// Reading here ensures the processed event uses the state for that render.
|
|
93
|
+
const state = event === 'update' ? getState() : getSnapshot();
|
|
94
|
+
|
|
95
|
+
if (
|
|
96
|
+
previous.listener === listener &&
|
|
97
|
+
(previous.state === state ||
|
|
98
|
+
(event === 'update' &&
|
|
99
|
+
Object.is(select(previous.state), select(state))))
|
|
100
|
+
) {
|
|
101
|
+
return previous;
|
|
82
102
|
}
|
|
103
|
+
|
|
104
|
+
return { listener, state };
|
|
83
105
|
},
|
|
84
|
-
|
|
106
|
+
undefined,
|
|
107
|
+
() => ({ listener, state: getState() })
|
|
85
108
|
);
|
|
86
109
|
|
|
87
|
-
|
|
88
|
-
? navigation.getState
|
|
89
|
-
: stateListener?.getState;
|
|
110
|
+
let state = entry.state;
|
|
90
111
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
112
|
+
const committedRef = React.useRef<{
|
|
113
|
+
entry: NavigationStateEntry | null;
|
|
114
|
+
state: NavigationState<ParamListBase>;
|
|
115
|
+
select: (state: NavigationState<ParamListBase>) => unknown;
|
|
116
|
+
}>({ entry: null, state, select });
|
|
94
117
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
118
|
+
React.useInsertionEffect(() => {
|
|
119
|
+
committedRef.current = { entry, state, select };
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const snapshot = getSnapshot();
|
|
123
|
+
|
|
124
|
+
const behind =
|
|
125
|
+
state !== snapshot &&
|
|
126
|
+
// A different listener means the state belongs to another navigator.
|
|
127
|
+
// This can happen when the passed route name changes.
|
|
128
|
+
(entry.listener !== listener ||
|
|
129
|
+
// An entry that advanced past the last commit is at least as new as the snapshot.
|
|
130
|
+
// An entry that didn't advance while the committed state changed is older.
|
|
131
|
+
entry === committedRef.current.entry);
|
|
132
|
+
|
|
133
|
+
if (behind) {
|
|
134
|
+
state = snapshot;
|
|
135
|
+
dispatch('commit');
|
|
99
136
|
}
|
|
100
137
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
138
|
+
React.useLayoutEffect(() => {
|
|
139
|
+
const check = (event: NavigationStateEvent) => {
|
|
140
|
+
const { state, select } = committedRef.current;
|
|
141
|
+
|
|
142
|
+
// An 'update' event follows the latest state in the lane the update was made in.
|
|
143
|
+
// A 'commit' event syncs the reducer to the state committed by the navigator.
|
|
144
|
+
const target = event === 'update' ? getState() : getSnapshot();
|
|
145
|
+
|
|
146
|
+
if (state !== target && !Object.is(select(state), select(target))) {
|
|
147
|
+
dispatch(event);
|
|
148
|
+
}
|
|
149
|
+
};
|
|
108
150
|
|
|
109
|
-
|
|
151
|
+
const unsubscribe = subscribe(check);
|
|
152
|
+
|
|
153
|
+
// The reducer may not match the committed state when the subscription starts.
|
|
154
|
+
// This happens on mount during a transition or an update before subscribing.
|
|
155
|
+
check('commit');
|
|
156
|
+
|
|
157
|
+
return unsubscribe;
|
|
158
|
+
}, [getState, getSnapshot, subscribe]);
|
|
159
|
+
|
|
160
|
+
return select(state);
|
|
110
161
|
}
|
|
111
162
|
|
|
112
163
|
export function NavigationStateListenerProvider({
|
|
113
164
|
state,
|
|
165
|
+
getState,
|
|
166
|
+
subscribe,
|
|
114
167
|
children,
|
|
115
168
|
}: {
|
|
116
169
|
state: NavigationState<ParamListBase>;
|
|
170
|
+
getState: () => NavigationState<ParamListBase>;
|
|
171
|
+
subscribe: (callback: () => void) => () => void;
|
|
117
172
|
children: React.ReactNode;
|
|
118
173
|
}) {
|
|
119
|
-
const
|
|
174
|
+
const snapshotRef = React.useRef(state);
|
|
120
175
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
listeners.current.push(callback);
|
|
176
|
+
React.useInsertionEffect(() => {
|
|
177
|
+
snapshotRef.current = state;
|
|
178
|
+
}, [state]);
|
|
125
179
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
});
|
|
180
|
+
const [listeners] = React.useState(
|
|
181
|
+
() => new Set<(event: NavigationStateEvent) => void>()
|
|
182
|
+
);
|
|
130
183
|
|
|
131
|
-
React.
|
|
132
|
-
listeners.
|
|
133
|
-
}, [state]);
|
|
184
|
+
React.useLayoutEffect(() => {
|
|
185
|
+
listeners.forEach((listener) => listener('commit'));
|
|
186
|
+
}, [listeners, state]);
|
|
134
187
|
|
|
135
188
|
const context = React.useMemo(
|
|
136
189
|
() => ({
|
|
137
190
|
getState,
|
|
138
|
-
|
|
191
|
+
getSnapshot: () => snapshotRef.current,
|
|
192
|
+
subscribe: (callback: (event: NavigationStateEvent) => void) => {
|
|
193
|
+
const unsubscribe = subscribe(() => callback('update'));
|
|
194
|
+
|
|
195
|
+
listeners.add(callback);
|
|
196
|
+
|
|
197
|
+
return () => {
|
|
198
|
+
listeners.delete(callback);
|
|
199
|
+
unsubscribe();
|
|
200
|
+
};
|
|
201
|
+
},
|
|
139
202
|
}),
|
|
140
|
-
[getState, subscribe]
|
|
203
|
+
[getState, listeners, subscribe]
|
|
141
204
|
);
|
|
142
205
|
|
|
143
206
|
return (
|
|
@@ -147,6 +210,42 @@ export function NavigationStateListenerProvider({
|
|
|
147
210
|
);
|
|
148
211
|
}
|
|
149
212
|
|
|
150
|
-
|
|
213
|
+
export function NamedNavigationStateListenerProvider({
|
|
214
|
+
name,
|
|
215
|
+
children,
|
|
216
|
+
}: {
|
|
217
|
+
name: string;
|
|
218
|
+
children: React.ReactNode;
|
|
219
|
+
}) {
|
|
220
|
+
const listener = React.use(NavigationStateListenerContext);
|
|
221
|
+
|
|
222
|
+
if (listener == null) {
|
|
223
|
+
throw new Error(
|
|
224
|
+
"Couldn't find a navigation state listener. This is likely because the navigator doesn't render its content under 'NavigationContent'."
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const parents = React.use(NamedNavigationStateListenerListContext);
|
|
229
|
+
|
|
230
|
+
const listeners = React.useMemo(
|
|
231
|
+
() => ({
|
|
232
|
+
...parents,
|
|
233
|
+
[name]: listener,
|
|
234
|
+
}),
|
|
235
|
+
[listener, name, parents]
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
return (
|
|
239
|
+
<NamedNavigationStateListenerListContext.Provider value={listeners}>
|
|
240
|
+
{children}
|
|
241
|
+
</NamedNavigationStateListenerListContext.Provider>
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export const NavigationStateListenerContext = React.createContext<
|
|
151
246
|
NavigationStateListener | undefined
|
|
152
247
|
>(undefined);
|
|
248
|
+
|
|
249
|
+
export const NamedNavigationStateListenerListContext = React.createContext<
|
|
250
|
+
Record<string, NavigationStateListener> | undefined
|
|
251
|
+
>(undefined);
|
package/src/useOnAction.tsx
CHANGED
|
@@ -7,20 +7,23 @@ import type {
|
|
|
7
7
|
} from '@react-navigation/routers';
|
|
8
8
|
import * as React from 'react';
|
|
9
9
|
|
|
10
|
+
import { ConsumedParamsContext } from './ConsumedParamsContext';
|
|
11
|
+
import { getLoaderForStateChange } from './DataLoading';
|
|
10
12
|
import {
|
|
11
13
|
type ChildActionListener,
|
|
12
14
|
type ChildBeforeRemoveListener,
|
|
13
15
|
NavigationBuilderContext,
|
|
14
16
|
} from './NavigationBuilderContext';
|
|
17
|
+
import { StaticTreeContext } from './StaticTreeContext';
|
|
15
18
|
import type { EventMapCore } from './types';
|
|
16
19
|
import type { NavigationEventEmitter } from './useEventEmitter';
|
|
17
20
|
import { shouldPreventRemove, useOnPreventRemove } from './useOnPreventRemove';
|
|
18
21
|
|
|
19
|
-
type Options = {
|
|
20
|
-
router: Router<
|
|
21
|
-
key?: string;
|
|
22
|
-
getState: () =>
|
|
23
|
-
setState: (state:
|
|
22
|
+
type Options<State extends NavigationState> = {
|
|
23
|
+
router: Router<State, NavigationAction>;
|
|
24
|
+
key?: string | undefined;
|
|
25
|
+
getState: () => State;
|
|
26
|
+
setState: (state: State | PartialState<State>) => void;
|
|
24
27
|
actionListeners: ChildActionListener[];
|
|
25
28
|
beforeRemoveListeners: Record<string, ChildBeforeRemoveListener | undefined>;
|
|
26
29
|
routerConfigOptions: RouterConfigOptions;
|
|
@@ -36,7 +39,7 @@ type Options = {
|
|
|
36
39
|
*
|
|
37
40
|
* When the action handler handles as action, it returns `true`, otherwise `false`.
|
|
38
41
|
*/
|
|
39
|
-
export function useOnAction({
|
|
42
|
+
export function useOnAction<State extends NavigationState>({
|
|
40
43
|
router,
|
|
41
44
|
getState,
|
|
42
45
|
setState,
|
|
@@ -45,18 +48,22 @@ export function useOnAction({
|
|
|
45
48
|
beforeRemoveListeners,
|
|
46
49
|
routerConfigOptions,
|
|
47
50
|
emitter,
|
|
48
|
-
}: Options) {
|
|
51
|
+
}: Options<State>) {
|
|
49
52
|
const {
|
|
50
53
|
onAction: onActionParent,
|
|
51
54
|
onRouteFocus: onRouteFocusParent,
|
|
52
55
|
addListener: addListenerParent,
|
|
53
56
|
onDispatchAction,
|
|
54
|
-
|
|
57
|
+
flushUpdates,
|
|
58
|
+
} = React.use(NavigationBuilderContext);
|
|
59
|
+
|
|
60
|
+
const tree = React.use(StaticTreeContext);
|
|
61
|
+
const consumedParams = React.use(ConsumedParamsContext);
|
|
55
62
|
|
|
56
63
|
const routerConfigOptionsRef =
|
|
57
64
|
React.useRef<RouterConfigOptions>(routerConfigOptions);
|
|
58
65
|
|
|
59
|
-
React.
|
|
66
|
+
React.useInsertionEffect(() => {
|
|
60
67
|
routerConfigOptionsRef.current = routerConfigOptions;
|
|
61
68
|
});
|
|
62
69
|
|
|
@@ -65,6 +72,11 @@ export function useOnAction({
|
|
|
65
72
|
action: NavigationAction,
|
|
66
73
|
visitedNavigators: Set<string> = new Set<string>()
|
|
67
74
|
) => {
|
|
75
|
+
// Apply any pending state updates scheduled during render before handling the action
|
|
76
|
+
// Otherwise the action will be handled with an outdated state,
|
|
77
|
+
// and the pending updates will overwrite the changes from the action
|
|
78
|
+
flushUpdates();
|
|
79
|
+
|
|
68
80
|
const state = getState();
|
|
69
81
|
|
|
70
82
|
// Since actions can bubble both up and down, they could come to the same navigator again
|
|
@@ -87,9 +99,18 @@ export function useOnAction({
|
|
|
87
99
|
result =
|
|
88
100
|
result === null && action.target === state.key ? state : result;
|
|
89
101
|
|
|
90
|
-
if (result !== null) {
|
|
91
|
-
|
|
102
|
+
if (result !== null && result.stale !== false) {
|
|
103
|
+
// Some actions (e.g. `RESET`) may return a stale state from the router
|
|
104
|
+
// We rehydrate it before storing so the stored state is always usable
|
|
105
|
+
// Otherwise anything reading the state before the next render
|
|
106
|
+
// (e.g. another dispatch immediately after) would get an outdated state
|
|
107
|
+
result = router.getRehydratedState(
|
|
108
|
+
result,
|
|
109
|
+
routerConfigOptionsRef.current
|
|
110
|
+
);
|
|
111
|
+
}
|
|
92
112
|
|
|
113
|
+
if (result !== null) {
|
|
93
114
|
if (state !== result) {
|
|
94
115
|
const isPrevented = shouldPreventRemove(
|
|
95
116
|
emitter,
|
|
@@ -100,10 +121,34 @@ export function useOnAction({
|
|
|
100
121
|
);
|
|
101
122
|
|
|
102
123
|
if (isPrevented) {
|
|
124
|
+
onDispatchAction(action, true);
|
|
125
|
+
|
|
103
126
|
return true;
|
|
104
127
|
}
|
|
105
128
|
|
|
129
|
+
if (getState() !== state) {
|
|
130
|
+
// Listeners for 'beforeRemove' may dispatch actions that change the state
|
|
131
|
+
// Then the result we have is outdated and would overwrite those changes
|
|
132
|
+
// So we handle the action again to calculate the result with the latest state
|
|
133
|
+
return onAction(action, new Set<string>());
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
onDispatchAction(action, false);
|
|
137
|
+
|
|
138
|
+
if (tree) {
|
|
139
|
+
const loader = getLoaderForStateChange(
|
|
140
|
+
tree,
|
|
141
|
+
result,
|
|
142
|
+
state,
|
|
143
|
+
consumedParams
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
loader?.();
|
|
147
|
+
}
|
|
148
|
+
|
|
106
149
|
setState(result);
|
|
150
|
+
} else {
|
|
151
|
+
onDispatchAction(action, true);
|
|
107
152
|
}
|
|
108
153
|
|
|
109
154
|
if (onRouteFocusParent !== undefined) {
|
|
@@ -132,7 +177,7 @@ export function useOnAction({
|
|
|
132
177
|
for (let i = actionListeners.length - 1; i >= 0; i--) {
|
|
133
178
|
const listener = actionListeners[i];
|
|
134
179
|
|
|
135
|
-
if (listener(action, visitedNavigators)) {
|
|
180
|
+
if (listener?.(action, visitedNavigators)) {
|
|
136
181
|
return true;
|
|
137
182
|
}
|
|
138
183
|
}
|
|
@@ -143,7 +188,9 @@ export function useOnAction({
|
|
|
143
188
|
[
|
|
144
189
|
actionListeners,
|
|
145
190
|
beforeRemoveListeners,
|
|
191
|
+
consumedParams,
|
|
146
192
|
emitter,
|
|
193
|
+
flushUpdates,
|
|
147
194
|
getState,
|
|
148
195
|
key,
|
|
149
196
|
onActionParent,
|
|
@@ -151,6 +198,7 @@ export function useOnAction({
|
|
|
151
198
|
onRouteFocusParent,
|
|
152
199
|
router,
|
|
153
200
|
setState,
|
|
201
|
+
tree,
|
|
154
202
|
]
|
|
155
203
|
);
|
|
156
204
|
|
|
@@ -160,7 +208,7 @@ export function useOnAction({
|
|
|
160
208
|
beforeRemoveListeners,
|
|
161
209
|
});
|
|
162
210
|
|
|
163
|
-
React.
|
|
211
|
+
React.useInsertionEffect(
|
|
164
212
|
() => addListenerParent?.('action', onAction),
|
|
165
213
|
[addListenerParent, onAction]
|
|
166
214
|
);
|