@react-navigation/core 8.0.0-alpha.2 → 8.0.0-alpha.21
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 +20 -9
- 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/NavigationBuilderContext.js +1 -0
- package/lib/module/NavigationBuilderContext.js.map +1 -1
- package/lib/module/NavigationIndependentTree.js +8 -4
- package/lib/module/NavigationIndependentTree.js.map +1 -1
- package/lib/module/NavigationProvider.js +14 -3
- package/lib/module/NavigationProvider.js.map +1 -1
- package/lib/module/NavigationStateContext.js.map +1 -1
- package/lib/module/PreventRemoveProvider.js +3 -3
- package/lib/module/PreventRemoveProvider.js.map +1 -1
- package/lib/module/SceneView.js +46 -56
- package/lib/module/SceneView.js.map +1 -1
- package/lib/module/StaticNavigation.js +166 -46
- package/lib/module/StaticNavigation.js.map +1 -1
- package/lib/module/checkSerializable.js +11 -4
- package/lib/module/checkSerializable.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 +40 -14
- package/lib/module/getActionFromState.js.map +1 -1
- package/lib/module/getPathFromState.js +48 -11
- package/lib/module/getPathFromState.js.map +1 -1
- package/lib/module/getPatternParts.js +3 -0
- package/lib/module/getPatternParts.js.map +1 -1
- package/lib/module/getStateFromPath.js +353 -166
- package/lib/module/getStateFromPath.js.map +1 -1
- package/lib/module/getStateFromRouteParams.js +24 -0
- package/lib/module/getStateFromRouteParams.js.map +1 -0
- package/lib/module/index.js +3 -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 +15 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/useDescriptors.js +18 -9
- package/lib/module/useDescriptors.js.map +1 -1
- package/lib/module/useEventEmitter.js +43 -31
- package/lib/module/useEventEmitter.js.map +1 -1
- package/lib/module/useFocusEvents.js +6 -2
- 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/useNavigation.js.map +1 -1
- package/lib/module/useNavigationBuilder.js +144 -86
- package/lib/module/useNavigationBuilder.js.map +1 -1
- package/lib/module/useNavigationCache.js +3 -3
- package/lib/module/useNavigationCache.js.map +1 -1
- package/lib/module/useNavigationHelpers.js +1 -1
- 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 +6 -4
- package/lib/module/useNavigationState.js.map +1 -1
- package/lib/module/useOnAction.js +3 -3
- 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 +3 -3
- 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 +7 -4
- package/lib/module/useOptionsGetters.js.map +1 -1
- package/lib/module/usePreventRemove.js +1 -1
- 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.map +1 -1
- package/lib/module/useRouteCache.js +2 -1
- package/lib/module/useRouteCache.js.map +1 -1
- package/lib/module/useScheduleUpdate.js +1 -1
- 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/validatePathConfig.js +2 -1
- 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 +8 -0
- package/lib/typescript/src/ConsumedParamsContext.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 +12 -6
- 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 +10 -10
- package/lib/typescript/src/NavigationProvider.d.ts.map +1 -1
- package/lib/typescript/src/NavigationStateContext.d.ts +3 -3
- package/lib/typescript/src/NavigationStateContext.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 +3 -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 +123 -92
- package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
- package/lib/typescript/src/checkSerializable.d.ts +5 -3
- 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 +17 -5
- package/lib/typescript/src/createNavigatorFactory.d.ts.map +1 -1
- package/lib/typescript/src/findFocusedRoute.d.ts +3 -3
- 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 +5 -5
- 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 +34 -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 +215 -131
- 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 +7 -7
- package/lib/typescript/src/useDescriptors.d.ts.map +1 -1
- package/lib/typescript/src/useEventEmitter.d.ts +1 -1
- 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/useNavigation.d.ts +4 -2
- package/lib/typescript/src/useNavigation.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationBuilder.d.ts +24 -24
- 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 -19
- package/lib/typescript/src/useNavigationHelpers.d.ts.map +1 -1
- package/lib/typescript/src/useNavigationState.d.ts +2 -2
- 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 +3 -3
- 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/usePreventRemoveContext.d.ts +1 -1
- package/lib/typescript/src/useRoute.d.ts +2 -2
- package/lib/typescript/src/useRoute.d.ts.map +1 -1
- package/lib/typescript/src/useRouteCache.d.ts +4 -4
- package/lib/typescript/src/useRouteCache.d.ts.map +1 -1
- 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/utilities.d.ts +45 -5
- package/lib/typescript/src/utilities.d.ts.map +1 -1
- package/lib/typescript/src/validatePathConfig.d.ts.map +1 -1
- package/package.json +23 -20
- package/src/BaseNavigationContainer.tsx +337 -326
- package/src/ConsumedParamsContext.tsx +10 -0
- package/src/NavigationBuilderContext.tsx +14 -8
- package/src/NavigationFocusedRouteStateContext.tsx +4 -4
- package/src/NavigationIndependentTree.tsx +8 -5
- package/src/NavigationProvider.tsx +17 -3
- package/src/NavigationStateContext.tsx +5 -6
- package/src/PreventRemoveProvider.tsx +3 -3
- package/src/SceneView.tsx +58 -56
- package/src/StaticNavigation.tsx +488 -250
- package/src/checkSerializable.tsx +22 -12
- package/src/createNavigatorFactory.tsx +83 -8
- package/src/findFocusedRoute.tsx +13 -8
- package/src/getActionFromState.tsx +68 -39
- package/src/getPathFromState.tsx +91 -27
- package/src/getPatternParts.tsx +8 -0
- package/src/getStateFromPath.tsx +555 -180
- package/src/getStateFromRouteParams.tsx +60 -0
- package/src/index.tsx +47 -5
- package/src/theming/useTheme.tsx +1 -1
- package/src/types.tsx +541 -338
- package/src/useDescriptors.tsx +27 -12
- package/src/useEventEmitter.tsx +45 -36
- package/src/useFocusEvents.tsx +8 -2
- package/src/useFocusedListenersChildrenAdapter.tsx +2 -2
- package/src/useIsFocused.tsx +14 -21
- package/src/useNavigation.tsx +5 -3
- package/src/useNavigationBuilder.tsx +220 -132
- package/src/useNavigationCache.tsx +6 -6
- package/src/useNavigationHelpers.tsx +1 -1
- package/src/useNavigationIndependentTree.tsx +1 -1
- package/src/useNavigationState.tsx +11 -7
- package/src/useOnAction.tsx +10 -10
- package/src/useOnGetState.tsx +5 -3
- package/src/useOnPreventRemove.tsx +3 -3
- package/src/useOnRouteFocus.tsx +10 -12
- package/src/useOptionsGetters.tsx +7 -4
- package/src/usePreventRemove.tsx +1 -1
- package/src/usePreventRemoveContext.tsx +1 -1
- package/src/useRegisterNavigator.tsx +2 -2
- package/src/useRoute.tsx +4 -2
- package/src/useRouteCache.tsx +2 -1
- package/src/useScheduleUpdate.tsx +1 -3
- package/src/useStateForPath.tsx +1 -1
- package/src/utilities.tsx +101 -5
- package/src/validatePathConfig.tsx +1 -0
- 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
|
@@ -15,10 +15,12 @@ import * as React from 'react';
|
|
|
15
15
|
import { isValidElementType } from 'react-is';
|
|
16
16
|
import useLatestCallback from 'use-latest-callback';
|
|
17
17
|
|
|
18
|
+
import { ConsumedParamsContext } from './ConsumedParamsContext';
|
|
18
19
|
import { deepFreeze } from './deepFreeze';
|
|
19
20
|
import { Group } from './Group';
|
|
20
21
|
import { isArrayEqual } from './isArrayEqual';
|
|
21
22
|
import { isRecordEqual } from './isRecordEqual';
|
|
23
|
+
import { NavigationBuilderContext } from './NavigationBuilderContext';
|
|
22
24
|
import { NavigationHelpersContext } from './NavigationHelpersContext';
|
|
23
25
|
import { NavigationMetaContext } from './NavigationMetaContext';
|
|
24
26
|
import { NavigationRouteContext } from './NavigationProvider';
|
|
@@ -36,11 +38,11 @@ import {
|
|
|
36
38
|
import { UnhandledActionContext } from './UnhandledActionContext';
|
|
37
39
|
import { useChildListeners } from './useChildListeners';
|
|
38
40
|
import { useComponent } from './useComponent';
|
|
39
|
-
import { useCurrentRender } from './useCurrentRender';
|
|
40
41
|
import { type ScreenConfigWithParent, useDescriptors } from './useDescriptors';
|
|
41
42
|
import { useEventEmitter } from './useEventEmitter';
|
|
42
43
|
import { useFocusedListenersChildrenAdapter } from './useFocusedListenersChildrenAdapter';
|
|
43
44
|
import { useFocusEvents } from './useFocusEvents';
|
|
45
|
+
import { FocusedRouteKeyContext } from './useIsFocused';
|
|
44
46
|
import { useKeyedChildListeners } from './useKeyedChildListeners';
|
|
45
47
|
import { useLazyValue } from './useLazyValue';
|
|
46
48
|
import { useNavigationHelpers } from './useNavigationHelpers';
|
|
@@ -57,9 +59,17 @@ PrivateValueStore;
|
|
|
57
59
|
|
|
58
60
|
type NavigatorRoute = {
|
|
59
61
|
key: string;
|
|
60
|
-
params?: NavigatorScreenParams<ParamListBase
|
|
62
|
+
params?: NavigatorScreenParams<ParamListBase> | undefined;
|
|
61
63
|
};
|
|
62
64
|
|
|
65
|
+
const isNavigationState = (
|
|
66
|
+
state: unknown
|
|
67
|
+
): state is NavigationState | PartialState<NavigationState> =>
|
|
68
|
+
state != null &&
|
|
69
|
+
typeof state === 'object' &&
|
|
70
|
+
'routes' in state &&
|
|
71
|
+
Array.isArray(state.routes);
|
|
72
|
+
|
|
63
73
|
const isScreen = (
|
|
64
74
|
child: React.ReactElement<unknown>
|
|
65
75
|
): child is React.ReactElement<{
|
|
@@ -276,8 +286,10 @@ const getRouteConfigsFromChildren = <
|
|
|
276
286
|
};
|
|
277
287
|
|
|
278
288
|
const getStateFromParams = (params: NavigatorRoute['params']) => {
|
|
279
|
-
|
|
280
|
-
|
|
289
|
+
const state = params?.state;
|
|
290
|
+
|
|
291
|
+
if (isNavigationState(state)) {
|
|
292
|
+
return state;
|
|
281
293
|
} else if (typeof params?.screen === 'string' && params?.initial !== false) {
|
|
282
294
|
return {
|
|
283
295
|
routes: [
|
|
@@ -319,9 +331,14 @@ export function useNavigationBuilder<
|
|
|
319
331
|
) {
|
|
320
332
|
const navigatorKey = useRegisterNavigator();
|
|
321
333
|
|
|
322
|
-
const route = React.
|
|
323
|
-
|
|
324
|
-
|
|
334
|
+
const route = React.use(NavigationRouteContext) as NavigatorRoute | undefined;
|
|
335
|
+
|
|
336
|
+
const consumedParams = React.use(ConsumedParamsContext);
|
|
337
|
+
|
|
338
|
+
const isNestedParamsConsumed =
|
|
339
|
+
typeof route?.params === 'object' && route.params != null
|
|
340
|
+
? consumedParams?.isConsumed(route.params)
|
|
341
|
+
: false;
|
|
325
342
|
|
|
326
343
|
const {
|
|
327
344
|
children,
|
|
@@ -365,44 +382,7 @@ export function useNavigationBuilder<
|
|
|
365
382
|
return original;
|
|
366
383
|
});
|
|
367
384
|
|
|
368
|
-
const screens = routeConfigs.reduce<
|
|
369
|
-
Record<string, ScreenConfigWithParent<State, ScreenOptions, EventMap>>
|
|
370
|
-
>((acc, config) => {
|
|
371
|
-
if (config.props.name in acc) {
|
|
372
|
-
throw new Error(
|
|
373
|
-
`A navigator cannot contain multiple 'Screen' components with the same name (found duplicate screen named '${config.props.name}')`
|
|
374
|
-
);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
acc[config.props.name] = config;
|
|
378
|
-
return acc;
|
|
379
|
-
}, {});
|
|
380
|
-
|
|
381
385
|
const routeNames = routeConfigs.map((config) => config.props.name);
|
|
382
|
-
const routeKeyList = routeNames.reduce<Record<string, React.Key | undefined>>(
|
|
383
|
-
(acc, curr) => {
|
|
384
|
-
acc[curr] = screens[curr].keys.map((key) => key ?? '').join(':');
|
|
385
|
-
return acc;
|
|
386
|
-
},
|
|
387
|
-
{}
|
|
388
|
-
);
|
|
389
|
-
const routeParamList = routeNames.reduce<Record<string, object | undefined>>(
|
|
390
|
-
(acc, curr) => {
|
|
391
|
-
const { initialParams } = screens[curr].props;
|
|
392
|
-
acc[curr] = initialParams;
|
|
393
|
-
return acc;
|
|
394
|
-
},
|
|
395
|
-
{}
|
|
396
|
-
);
|
|
397
|
-
const routeGetIdList = routeNames.reduce<
|
|
398
|
-
RouterConfigOptions['routeGetIdList']
|
|
399
|
-
>(
|
|
400
|
-
(acc, curr) =>
|
|
401
|
-
Object.assign(acc, {
|
|
402
|
-
[curr]: screens[curr].props.getId,
|
|
403
|
-
}),
|
|
404
|
-
{}
|
|
405
|
-
);
|
|
406
386
|
|
|
407
387
|
if (!routeNames.length) {
|
|
408
388
|
throw new Error(
|
|
@@ -410,6 +390,31 @@ export function useNavigationBuilder<
|
|
|
410
390
|
);
|
|
411
391
|
}
|
|
412
392
|
|
|
393
|
+
const screens: Record<
|
|
394
|
+
string,
|
|
395
|
+
ScreenConfigWithParent<State, ScreenOptions, EventMap>
|
|
396
|
+
> = {};
|
|
397
|
+
|
|
398
|
+
const routeKeyList: Record<string, React.Key | undefined> = {};
|
|
399
|
+
const routeParamList: Record<string, object | undefined> = {};
|
|
400
|
+
const routeGetIdList: RouterConfigOptions['routeGetIdList'] = {};
|
|
401
|
+
|
|
402
|
+
for (const config of routeConfigs) {
|
|
403
|
+
const name = config.props.name;
|
|
404
|
+
|
|
405
|
+
if (name in screens) {
|
|
406
|
+
throw new Error(
|
|
407
|
+
`A navigator cannot contain multiple 'Screen' components with the same name (found duplicate screen named '${name}')`
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
screens[name] = config;
|
|
412
|
+
routeKeyList[name] = config.keys.map((key) => key ?? '').join(':');
|
|
413
|
+
routeParamList[name] = config.props.initialParams;
|
|
414
|
+
|
|
415
|
+
Object.assign(routeGetIdList, { [name]: config.props.getId });
|
|
416
|
+
}
|
|
417
|
+
|
|
413
418
|
const isStateValid = React.useCallback(
|
|
414
419
|
(state: NavigationState | PartialState<NavigationState>) =>
|
|
415
420
|
state.type === undefined || state.type === router.type,
|
|
@@ -417,7 +422,9 @@ export function useNavigationBuilder<
|
|
|
417
422
|
);
|
|
418
423
|
|
|
419
424
|
const isStateInitialized = React.useCallback(
|
|
420
|
-
|
|
425
|
+
<T extends NavigationState>(
|
|
426
|
+
state: T | PartialState<T> | undefined
|
|
427
|
+
): state is T =>
|
|
421
428
|
state !== undefined && state.stale === false && isStateValid(state),
|
|
422
429
|
[isStateValid]
|
|
423
430
|
);
|
|
@@ -435,16 +442,22 @@ export function useNavigationBuilder<
|
|
|
435
442
|
setKey,
|
|
436
443
|
getKey,
|
|
437
444
|
getIsInitial,
|
|
438
|
-
} = React.
|
|
445
|
+
} = React.use(NavigationStateContext);
|
|
439
446
|
|
|
440
|
-
const
|
|
447
|
+
const stateCleanupRef = React.useRef<boolean>(false);
|
|
448
|
+
const lastStateRef = React.useRef<State | PartialState<State> | undefined>(
|
|
449
|
+
undefined
|
|
450
|
+
);
|
|
441
451
|
|
|
442
452
|
const setState = useLatestCallback(
|
|
443
|
-
(state:
|
|
444
|
-
if (
|
|
453
|
+
(state: State | PartialState<State> | undefined) => {
|
|
454
|
+
if (stateCleanupRef.current) {
|
|
455
|
+
// Store the state locally in case the current navigator is in `Activity`
|
|
456
|
+
lastStateRef.current = state;
|
|
457
|
+
|
|
445
458
|
// State might have been already cleaned up due to unmount
|
|
446
|
-
// We
|
|
447
|
-
//
|
|
459
|
+
// We don't want to update `route.state` in parent
|
|
460
|
+
// Otherwise it will be reused if a new navigator gets mounted
|
|
448
461
|
return;
|
|
449
462
|
}
|
|
450
463
|
|
|
@@ -456,15 +469,36 @@ export function useNavigationBuilder<
|
|
|
456
469
|
stateBeforeInitialization,
|
|
457
470
|
initializedState,
|
|
458
471
|
isFirstStateInitialization,
|
|
472
|
+
paramsUsedForInitialization,
|
|
459
473
|
] = React.useMemo((): [
|
|
460
474
|
PartialState<State> | undefined,
|
|
461
475
|
State | undefined,
|
|
462
476
|
boolean,
|
|
477
|
+
object | undefined,
|
|
463
478
|
] => {
|
|
479
|
+
// If the state was already cleaned up, but we have it stored in ref,
|
|
480
|
+
// It likely got cleaned up due to `<Activity mode="hidden">`
|
|
481
|
+
// We should reuse this state to avoid remounting screens
|
|
482
|
+
if (
|
|
483
|
+
stateCleanupRef.current &&
|
|
484
|
+
lastStateRef.current &&
|
|
485
|
+
isStateValid(lastStateRef.current)
|
|
486
|
+
) {
|
|
487
|
+
const state: State = isStateInitialized(lastStateRef.current)
|
|
488
|
+
? lastStateRef.current
|
|
489
|
+
: router.getRehydratedState(lastStateRef.current, {
|
|
490
|
+
routeNames,
|
|
491
|
+
routeParamList,
|
|
492
|
+
routeGetIdList,
|
|
493
|
+
});
|
|
494
|
+
|
|
495
|
+
return [undefined, state, false, undefined];
|
|
496
|
+
}
|
|
497
|
+
|
|
464
498
|
const initialRouteParamList = routeNames.reduce<
|
|
465
499
|
Record<string, object | undefined>
|
|
466
500
|
>((acc, curr) => {
|
|
467
|
-
const { initialParams } = screens[curr]
|
|
501
|
+
const { initialParams } = screens[curr]?.props ?? {};
|
|
468
502
|
const initialParamsFromParams =
|
|
469
503
|
route?.params?.state == null &&
|
|
470
504
|
route?.params?.initial !== false &&
|
|
@@ -493,7 +527,8 @@ export function useNavigationBuilder<
|
|
|
493
527
|
!(
|
|
494
528
|
typeof route?.params?.screen === 'string' &&
|
|
495
529
|
route?.params?.initial !== false
|
|
496
|
-
)
|
|
530
|
+
) &&
|
|
531
|
+
!isNestedParamsConsumed
|
|
497
532
|
) {
|
|
498
533
|
return [
|
|
499
534
|
undefined,
|
|
@@ -503,28 +538,40 @@ export function useNavigationBuilder<
|
|
|
503
538
|
routeGetIdList,
|
|
504
539
|
}),
|
|
505
540
|
true,
|
|
541
|
+
undefined,
|
|
506
542
|
];
|
|
507
543
|
} else {
|
|
508
|
-
const
|
|
509
|
-
const
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
544
|
+
const paramsForState = isNestedParamsConsumed ? undefined : route?.params;
|
|
545
|
+
const stateFromParams = paramsForState
|
|
546
|
+
? getStateFromParams(paramsForState)
|
|
547
|
+
: undefined;
|
|
548
|
+
|
|
549
|
+
const stateBeforeInitialization = (stateFromParams ?? currentState) as
|
|
550
|
+
| PartialState<State>
|
|
551
|
+
| undefined;
|
|
552
|
+
|
|
553
|
+
const hydratedState =
|
|
554
|
+
stateBeforeInitialization == null
|
|
555
|
+
? router.getInitialState({
|
|
556
|
+
routeNames,
|
|
557
|
+
routeParamList: initialRouteParamList,
|
|
558
|
+
routeGetIdList,
|
|
559
|
+
})
|
|
560
|
+
: router.getRehydratedState(stateBeforeInitialization, {
|
|
561
|
+
routeNames,
|
|
562
|
+
routeParamList: initialRouteParamList,
|
|
563
|
+
routeGetIdList,
|
|
564
|
+
});
|
|
519
565
|
|
|
520
566
|
if (
|
|
567
|
+
stateBeforeInitialization != null &&
|
|
521
568
|
options.routeNamesChangeBehavior === 'lastUnhandled' &&
|
|
522
569
|
doesStateHaveOnlyInvalidRoutes(stateBeforeInitialization)
|
|
523
570
|
) {
|
|
524
|
-
return [stateBeforeInitialization, hydratedState, true];
|
|
571
|
+
return [stateBeforeInitialization, hydratedState, true, paramsForState];
|
|
525
572
|
}
|
|
526
573
|
|
|
527
|
-
return [undefined, hydratedState, false];
|
|
574
|
+
return [undefined, hydratedState, false, paramsForState];
|
|
528
575
|
}
|
|
529
576
|
// We explicitly don't include routeNames, route.params etc. in the dep list
|
|
530
577
|
// below. We want to avoid forcing a new state to be calculated in those cases
|
|
@@ -602,38 +649,33 @@ export function useNavigationBuilder<
|
|
|
602
649
|
});
|
|
603
650
|
}
|
|
604
651
|
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
React.useEffect(() => {
|
|
608
|
-
previousNestedParamsRef.current = route?.params;
|
|
609
|
-
}, [route?.params]);
|
|
610
|
-
|
|
611
|
-
if (route?.params) {
|
|
612
|
-
const previousParams = previousNestedParamsRef.current;
|
|
652
|
+
let didConsumeNestedParams = route?.params === paramsUsedForInitialization;
|
|
613
653
|
|
|
654
|
+
if (route?.params && !didConsumeNestedParams) {
|
|
614
655
|
let action: CommonActions.Action | undefined;
|
|
656
|
+
const stateFromParams = route.params.state;
|
|
657
|
+
|
|
658
|
+
if (isNavigationState(stateFromParams) && !isNestedParamsConsumed) {
|
|
659
|
+
didConsumeNestedParams = true;
|
|
615
660
|
|
|
616
|
-
if (
|
|
617
|
-
typeof route.params.state === 'object' &&
|
|
618
|
-
route.params.state != null &&
|
|
619
|
-
route.params !== previousParams
|
|
620
|
-
) {
|
|
621
661
|
if (
|
|
622
662
|
options.routeNamesChangeBehavior === 'lastUnhandled' &&
|
|
623
|
-
doesStateHaveOnlyInvalidRoutes(
|
|
663
|
+
doesStateHaveOnlyInvalidRoutes(stateFromParams)
|
|
624
664
|
) {
|
|
625
|
-
if (
|
|
626
|
-
setUnhandledState(
|
|
665
|
+
if (stateFromParams !== unhandledState) {
|
|
666
|
+
setUnhandledState(stateFromParams);
|
|
627
667
|
}
|
|
628
668
|
} else {
|
|
629
669
|
// If the route was updated with new state, we should reset to it
|
|
630
|
-
action = CommonActions.reset(
|
|
670
|
+
action = CommonActions.reset(stateFromParams);
|
|
631
671
|
}
|
|
632
672
|
} else if (
|
|
633
673
|
typeof route.params.screen === 'string' &&
|
|
634
674
|
((route.params.initial === false && isFirstStateInitialization) ||
|
|
635
|
-
|
|
675
|
+
!isNestedParamsConsumed)
|
|
636
676
|
) {
|
|
677
|
+
didConsumeNestedParams = true;
|
|
678
|
+
|
|
637
679
|
if (
|
|
638
680
|
options.routeNamesChangeBehavior === 'lastUnhandled' &&
|
|
639
681
|
!routeNames.includes(route.params.screen)
|
|
@@ -674,14 +716,24 @@ export function useNavigationBuilder<
|
|
|
674
716
|
: nextState;
|
|
675
717
|
}
|
|
676
718
|
|
|
677
|
-
const
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
719
|
+
const setConsumedParams = consumedParams?.setConsumed;
|
|
720
|
+
|
|
721
|
+
React.useEffect(() => {
|
|
722
|
+
if (
|
|
723
|
+
setConsumedParams &&
|
|
724
|
+
didConsumeNestedParams &&
|
|
725
|
+
typeof route?.params === 'object' &&
|
|
726
|
+
route.params != null
|
|
727
|
+
) {
|
|
728
|
+
setConsumedParams(route.params);
|
|
729
|
+
}
|
|
730
|
+
}, [didConsumeNestedParams, route?.params, setConsumedParams]);
|
|
731
|
+
|
|
732
|
+
const shouldUpdate = state !== nextState;
|
|
681
733
|
|
|
682
734
|
useScheduleUpdate(() => {
|
|
683
735
|
if (shouldUpdate) {
|
|
684
|
-
//
|
|
736
|
+
// Schedule an update if the state needs to be updated
|
|
685
737
|
setState(nextState);
|
|
686
738
|
|
|
687
739
|
if (shouldClearUnhandledState) {
|
|
@@ -695,26 +747,41 @@ export function useNavigationBuilder<
|
|
|
695
747
|
// So we override the state object we return to use the latest state as soon as possible
|
|
696
748
|
state = nextState;
|
|
697
749
|
|
|
750
|
+
// Last state to reuse if component gets cleaned up due to `<Activity mode="hidden">`
|
|
751
|
+
React.useEffect(() => {
|
|
752
|
+
lastStateRef.current = state;
|
|
753
|
+
});
|
|
754
|
+
|
|
755
|
+
const lastNotifiedStateRef = React.useRef<State | null>(null);
|
|
756
|
+
|
|
698
757
|
React.useEffect(() => {
|
|
699
758
|
// In strict mode, React will double-invoke effects.
|
|
700
759
|
// So we need to reset the flag if component was not unmounted
|
|
701
|
-
|
|
760
|
+
stateCleanupRef.current = false;
|
|
702
761
|
|
|
703
762
|
setKey(navigatorKey);
|
|
704
763
|
|
|
705
|
-
if (!getIsInitial()) {
|
|
764
|
+
if (!getIsInitial() && lastNotifiedStateRef.current !== state) {
|
|
706
765
|
// If it's not initial render, we need to update the state
|
|
707
766
|
// This will make sure that our container gets notifier of state changes due to new mounts
|
|
708
767
|
// This is necessary for proper screen tracking, URL updates etc.
|
|
709
|
-
|
|
768
|
+
// We only notify if the state is different what we already notified
|
|
769
|
+
// Otherwise this goes into a loop when inside `<Activity mode="hidden">`
|
|
770
|
+
setState(state);
|
|
771
|
+
lastNotifiedStateRef.current = state;
|
|
710
772
|
}
|
|
711
773
|
|
|
712
774
|
return () => {
|
|
713
775
|
// We need to clean up state for this navigator on unmount
|
|
714
776
|
if (getCurrentState() !== undefined && getKey() === navigatorKey) {
|
|
715
777
|
setCurrentState(undefined);
|
|
716
|
-
|
|
778
|
+
stateCleanupRef.current = true;
|
|
717
779
|
}
|
|
780
|
+
|
|
781
|
+
// Reset so that StrictMode's second mount re-propagates state correctly.
|
|
782
|
+
// Without this, the guard above sees the same reference and skips setState,
|
|
783
|
+
// causing the initial state to be lost after cleanup wipes the container state.
|
|
784
|
+
lastNotifiedStateRef.current = null;
|
|
718
785
|
};
|
|
719
786
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
720
787
|
}, []);
|
|
@@ -742,6 +809,8 @@ export function useNavigationBuilder<
|
|
|
742
809
|
);
|
|
743
810
|
});
|
|
744
811
|
|
|
812
|
+
const { onEmitEvent } = React.use(NavigationBuilderContext);
|
|
813
|
+
|
|
745
814
|
const emitter = useEventEmitter<EventMapCore<State>>((e) => {
|
|
746
815
|
const routeNames = [];
|
|
747
816
|
|
|
@@ -764,35 +833,54 @@ export function useNavigationBuilder<
|
|
|
764
833
|
return;
|
|
765
834
|
}
|
|
766
835
|
|
|
767
|
-
const
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
836
|
+
const hasPerScreenListeners = routeNames.some(
|
|
837
|
+
(name) => screens[name]?.props.listeners != null
|
|
838
|
+
);
|
|
839
|
+
|
|
840
|
+
if (screenListeners != null || hasPerScreenListeners) {
|
|
841
|
+
const descriptor = descriptors[route.key];
|
|
842
|
+
|
|
843
|
+
if (descriptor == null) {
|
|
844
|
+
throw new Error(`Couldn't find a descriptor for route '${route.key}'.`);
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
const navigation = descriptor.navigation;
|
|
848
|
+
|
|
849
|
+
const listeners = ([] as (((e: any) => void) | undefined)[])
|
|
850
|
+
.concat(
|
|
851
|
+
// Get an array of listeners for all screens + common listeners on navigator
|
|
852
|
+
...[
|
|
853
|
+
screenListeners,
|
|
854
|
+
...routeNames.map((name) => {
|
|
855
|
+
const { listeners } = screens[name]?.props ?? {};
|
|
856
|
+
return listeners;
|
|
857
|
+
}),
|
|
858
|
+
].map((listeners) => {
|
|
859
|
+
const map =
|
|
860
|
+
typeof listeners === 'function'
|
|
861
|
+
? listeners({ route: route as any, navigation })
|
|
862
|
+
: listeners;
|
|
863
|
+
|
|
864
|
+
return map
|
|
865
|
+
? Object.keys(map)
|
|
866
|
+
.filter((type) => type === e.type)
|
|
867
|
+
.map((type) => map?.[type])
|
|
868
|
+
: undefined;
|
|
869
|
+
})
|
|
870
|
+
)
|
|
871
|
+
// We don't want same listener to be called multiple times for same event
|
|
872
|
+
// So we remove any duplicate functions from the array
|
|
873
|
+
.filter((cb, i, self) => cb && self.lastIndexOf(cb) === i);
|
|
874
|
+
|
|
875
|
+
listeners.forEach((listener) => listener?.(e));
|
|
876
|
+
}
|
|
794
877
|
|
|
795
|
-
|
|
878
|
+
onEmitEvent({
|
|
879
|
+
type: e.type,
|
|
880
|
+
data: e.data,
|
|
881
|
+
target: e.target,
|
|
882
|
+
defaultPrevented: e.defaultPrevented,
|
|
883
|
+
});
|
|
796
884
|
});
|
|
797
885
|
|
|
798
886
|
useFocusEvents({ state, emitter });
|
|
@@ -827,7 +915,7 @@ export function useNavigationBuilder<
|
|
|
827
915
|
setState,
|
|
828
916
|
});
|
|
829
917
|
|
|
830
|
-
const onUnhandledActionParent = React.
|
|
918
|
+
const onUnhandledActionParent = React.use(UnhandledActionContext);
|
|
831
919
|
|
|
832
920
|
const onUnhandledAction = useLatestCallback((action: NavigationAction) => {
|
|
833
921
|
if (
|
|
@@ -893,9 +981,7 @@ export function useNavigationBuilder<
|
|
|
893
981
|
ScreenOptions,
|
|
894
982
|
EventMap
|
|
895
983
|
>({
|
|
896
|
-
routes:
|
|
897
|
-
? router.getRoutesFromState(state)
|
|
898
|
-
: state.routes,
|
|
984
|
+
routes: state.routes,
|
|
899
985
|
screens,
|
|
900
986
|
navigation,
|
|
901
987
|
screenOptions,
|
|
@@ -911,13 +997,13 @@ export function useNavigationBuilder<
|
|
|
911
997
|
emitter,
|
|
912
998
|
});
|
|
913
999
|
|
|
914
|
-
useCurrentRender({
|
|
915
|
-
state,
|
|
916
|
-
navigation,
|
|
917
|
-
descriptors,
|
|
918
|
-
});
|
|
919
|
-
|
|
920
1000
|
const NavigationContent = useComponent((children: React.ReactNode) => {
|
|
1001
|
+
const focusedRoute = state.routes[state.index];
|
|
1002
|
+
|
|
1003
|
+
if (focusedRoute == null) {
|
|
1004
|
+
throw new Error(`Couldn't find a route at index ${state.index}.`);
|
|
1005
|
+
}
|
|
1006
|
+
|
|
921
1007
|
const element =
|
|
922
1008
|
layout != null
|
|
923
1009
|
? layout({
|
|
@@ -932,7 +1018,9 @@ export function useNavigationBuilder<
|
|
|
932
1018
|
<NavigationMetaContext.Provider value={undefined}>
|
|
933
1019
|
<NavigationHelpersContext.Provider value={navigation}>
|
|
934
1020
|
<NavigationStateListenerProvider state={state}>
|
|
935
|
-
<
|
|
1021
|
+
<FocusedRouteKeyContext.Provider value={focusedRoute.key}>
|
|
1022
|
+
<PreventRemoveProvider>{element}</PreventRemoveProvider>
|
|
1023
|
+
</FocusedRouteKeyContext.Provider>
|
|
936
1024
|
</NavigationStateListenerProvider>
|
|
937
1025
|
</NavigationHelpersContext.Provider>
|
|
938
1026
|
</NavigationMetaContext.Provider>
|
|
@@ -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
|
|
@@ -174,7 +174,7 @@ export function useNavigationCache<
|
|
|
174
174
|
|
|
175
175
|
return parentNavigationHelpers;
|
|
176
176
|
},
|
|
177
|
-
setOptions: (options:
|
|
177
|
+
setOptions: (options: Partial<ScreenOptions>) => {
|
|
178
178
|
setOptions((o) => ({
|
|
179
179
|
...o,
|
|
180
180
|
[route.key]: { ...o[route.key], ...options },
|
|
@@ -183,7 +183,7 @@ export function useNavigationCache<
|
|
|
183
183
|
isFocused: () => {
|
|
184
184
|
const state = rest.getState();
|
|
185
185
|
|
|
186
|
-
if (state.routes[state.index]
|
|
186
|
+
if (state.routes[state.index]?.key !== route.key) {
|
|
187
187
|
return false;
|
|
188
188
|
}
|
|
189
189
|
|
|
@@ -41,7 +41,7 @@ export function useNavigationHelpers<
|
|
|
41
41
|
router,
|
|
42
42
|
stateRef,
|
|
43
43
|
}: Options<State, Action>) {
|
|
44
|
-
const parentNavigationHelpers = React.
|
|
44
|
+
const parentNavigationHelpers = React.use(NavigationContext);
|
|
45
45
|
|
|
46
46
|
return React.useMemo(() => {
|
|
47
47
|
const dispatch = (op: Action | ((state: State) => Action)) => {
|
|
@@ -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
|
}
|
|
@@ -15,6 +15,8 @@ type NavigationStateListener = {
|
|
|
15
15
|
subscribe: (callback: () => void) => () => void;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
type UseNavigationForName = (name: string) => NavigationProp<ParamListBase>;
|
|
19
|
+
|
|
18
20
|
type NavigationStateForNested<
|
|
19
21
|
Navigator,
|
|
20
22
|
RouteName extends keyof NavigationListForNested<Navigator>,
|
|
@@ -35,8 +37,8 @@ type NavigationStateForNested<
|
|
|
35
37
|
export function useNavigationState<
|
|
36
38
|
const T,
|
|
37
39
|
const Navigator = RootNavigator,
|
|
38
|
-
const RouteName extends
|
|
39
|
-
keyof NavigationListForNested<Navigator
|
|
40
|
+
const RouteName extends keyof NavigationListForNested<Navigator> =
|
|
41
|
+
keyof NavigationListForNested<Navigator>,
|
|
40
42
|
>(
|
|
41
43
|
routeName: RouteName,
|
|
42
44
|
selector: (state: NavigationStateForNested<Navigator, RouteName>) => T
|
|
@@ -51,9 +53,9 @@ export function useNavigationState(...args: unknown[]): unknown {
|
|
|
51
53
|
|
|
52
54
|
if (typeof args[0] === 'string') {
|
|
53
55
|
// `useNavigation` uses `use` internally, so it's fine to call it conditionally
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
navigation = useNavigation(args[0]);
|
|
56
|
+
// Cast to a non-generic signature to skip overload resolution - otherwise TS
|
|
57
|
+
// eagerly expands `NavigationListForNested<RootNavigator>` at this call site.
|
|
58
|
+
navigation = (useNavigation as UseNavigationForName)(args[0]);
|
|
57
59
|
selector = args[1];
|
|
58
60
|
} else {
|
|
59
61
|
selector = args[0];
|
|
@@ -117,8 +119,9 @@ export function NavigationStateListenerProvider({
|
|
|
117
119
|
children: React.ReactNode;
|
|
118
120
|
}) {
|
|
119
121
|
const listeners = React.useRef<(() => void)[]>([]);
|
|
122
|
+
const stateRef = React.useRef(state);
|
|
120
123
|
|
|
121
|
-
const getState = useLatestCallback(() =>
|
|
124
|
+
const getState = useLatestCallback(() => stateRef.current);
|
|
122
125
|
|
|
123
126
|
const subscribe = useLatestCallback((callback: () => void) => {
|
|
124
127
|
listeners.current.push(callback);
|
|
@@ -128,7 +131,8 @@ export function NavigationStateListenerProvider({
|
|
|
128
131
|
};
|
|
129
132
|
});
|
|
130
133
|
|
|
131
|
-
React.
|
|
134
|
+
React.useLayoutEffect(() => {
|
|
135
|
+
stateRef.current = state;
|
|
132
136
|
listeners.current.forEach((callback) => callback());
|
|
133
137
|
}, [state]);
|
|
134
138
|
|