@react-navigation/core 8.0.0-alpha.23 → 8.0.0-alpha.25

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.
Files changed (153) hide show
  1. package/lib/module/BaseNavigationContainer.js +5 -2
  2. package/lib/module/BaseNavigationContainer.js.map +1 -1
  3. package/lib/module/DataLoading.js +102 -0
  4. package/lib/module/DataLoading.js.map +1 -0
  5. package/lib/module/NavigationBuilderContext.js.map +1 -1
  6. package/lib/module/NavigationIndependentTree.js +7 -6
  7. package/lib/module/NavigationIndependentTree.js.map +1 -1
  8. package/lib/module/NavigationProvider.js +12 -12
  9. package/lib/module/NavigationProvider.js.map +1 -1
  10. package/lib/module/PreventRemoveContext.js.map +1 -1
  11. package/lib/module/PreventRemoveProvider.js +34 -24
  12. package/lib/module/PreventRemoveProvider.js.map +1 -1
  13. package/lib/module/StaticNavigation.js +15 -7
  14. package/lib/module/StaticNavigation.js.map +1 -1
  15. package/lib/module/StaticTreeContext.js +5 -0
  16. package/lib/module/StaticTreeContext.js.map +1 -0
  17. package/lib/module/checkSerializable.js +7 -9
  18. package/lib/module/checkSerializable.js.map +1 -1
  19. package/lib/module/createNavigationContainerRef.js +6 -8
  20. package/lib/module/createNavigationContainerRef.js.map +1 -1
  21. package/lib/module/createNavigatorFactory.js.map +1 -1
  22. package/lib/module/getActionFromState.js +11 -11
  23. package/lib/module/getActionFromState.js.map +1 -1
  24. package/lib/module/getPathFromState.js +125 -96
  25. package/lib/module/getPathFromState.js.map +1 -1
  26. package/lib/module/getPatternParts.js +2 -2
  27. package/lib/module/getPatternParts.js.map +1 -1
  28. package/lib/module/getStateFromPath.js +136 -78
  29. package/lib/module/getStateFromPath.js.map +1 -1
  30. package/lib/module/index.js +1 -0
  31. package/lib/module/index.js.map +1 -1
  32. package/lib/module/types.js +13 -0
  33. package/lib/module/types.js.map +1 -1
  34. package/lib/module/useEventEmitter.js +5 -2
  35. package/lib/module/useEventEmitter.js.map +1 -1
  36. package/lib/module/useKeyedChildListeners.js +4 -2
  37. package/lib/module/useKeyedChildListeners.js.map +1 -1
  38. package/lib/module/useNavigation.js +2 -15
  39. package/lib/module/useNavigation.js.map +1 -1
  40. package/lib/module/useNavigationBuilder.js +5 -21
  41. package/lib/module/useNavigationBuilder.js.map +1 -1
  42. package/lib/module/useNavigationCache.js +19 -14
  43. package/lib/module/useNavigationCache.js.map +1 -1
  44. package/lib/module/useNavigationHelpers.js +27 -9
  45. package/lib/module/useNavigationHelpers.js.map +1 -1
  46. package/lib/module/useNavigationState.js +69 -36
  47. package/lib/module/useNavigationState.js.map +1 -1
  48. package/lib/module/useOnAction.js +25 -3
  49. package/lib/module/useOnAction.js.map +1 -1
  50. package/lib/module/useOnPreventRemove.js +35 -24
  51. package/lib/module/useOnPreventRemove.js.map +1 -1
  52. package/lib/module/useOptionsGetters.js +3 -1
  53. package/lib/module/useOptionsGetters.js.map +1 -1
  54. package/lib/module/usePreventRemove.js +9 -2
  55. package/lib/module/usePreventRemove.js.map +1 -1
  56. package/lib/module/useRoute.js.map +1 -1
  57. package/lib/module/useRouteCache.js +14 -7
  58. package/lib/module/useRouteCache.js.map +1 -1
  59. package/lib/module/useScheduleUpdate.js +8 -8
  60. package/lib/module/useScheduleUpdate.js.map +1 -1
  61. package/lib/module/useSyncState.js +4 -1
  62. package/lib/module/useSyncState.js.map +1 -1
  63. package/lib/module/validatePathConfig.js +50 -37
  64. package/lib/module/validatePathConfig.js.map +1 -1
  65. package/lib/typescript/src/BaseNavigationContainer.d.ts.map +1 -1
  66. package/lib/typescript/src/DataLoading.d.ts +20 -0
  67. package/lib/typescript/src/DataLoading.d.ts.map +1 -0
  68. package/lib/typescript/src/NavigationBuilderContext.d.ts +2 -2
  69. package/lib/typescript/src/NavigationBuilderContext.d.ts.map +1 -1
  70. package/lib/typescript/src/NavigationProvider.d.ts +0 -1
  71. package/lib/typescript/src/NavigationProvider.d.ts.map +1 -1
  72. package/lib/typescript/src/PreventRemoveContext.d.ts +1 -0
  73. package/lib/typescript/src/PreventRemoveContext.d.ts.map +1 -1
  74. package/lib/typescript/src/PreventRemoveProvider.d.ts.map +1 -1
  75. package/lib/typescript/src/StaticNavigation.d.ts +68 -42
  76. package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
  77. package/lib/typescript/src/StaticTreeContext.d.ts +4 -0
  78. package/lib/typescript/src/StaticTreeContext.d.ts.map +1 -0
  79. package/lib/typescript/src/checkSerializable.d.ts +4 -2
  80. package/lib/typescript/src/checkSerializable.d.ts.map +1 -1
  81. package/lib/typescript/src/createNavigationContainerRef.d.ts.map +1 -1
  82. package/lib/typescript/src/createNavigatorFactory.d.ts +11 -5
  83. package/lib/typescript/src/createNavigatorFactory.d.ts.map +1 -1
  84. package/lib/typescript/src/getActionFromState.d.ts.map +1 -1
  85. package/lib/typescript/src/getPathFromState.d.ts.map +1 -1
  86. package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
  87. package/lib/typescript/src/index.d.ts +2 -1
  88. package/lib/typescript/src/index.d.ts.map +1 -1
  89. package/lib/typescript/src/types.d.ts +84 -29
  90. package/lib/typescript/src/types.d.ts.map +1 -1
  91. package/lib/typescript/src/useEventEmitter.d.ts +1 -1
  92. package/lib/typescript/src/useEventEmitter.d.ts.map +1 -1
  93. package/lib/typescript/src/useKeyedChildListeners.d.ts.map +1 -1
  94. package/lib/typescript/src/useNavigation.d.ts.map +1 -1
  95. package/lib/typescript/src/useNavigationBuilder.d.ts +1 -1
  96. package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
  97. package/lib/typescript/src/useNavigationCache.d.ts.map +1 -1
  98. package/lib/typescript/src/useNavigationHelpers.d.ts +3 -4
  99. package/lib/typescript/src/useNavigationHelpers.d.ts.map +1 -1
  100. package/lib/typescript/src/useNavigationState.d.ts +11 -1
  101. package/lib/typescript/src/useNavigationState.d.ts.map +1 -1
  102. package/lib/typescript/src/useOnAction.d.ts.map +1 -1
  103. package/lib/typescript/src/useOnPreventRemove.d.ts +2 -6
  104. package/lib/typescript/src/useOnPreventRemove.d.ts.map +1 -1
  105. package/lib/typescript/src/useOptionsGetters.d.ts.map +1 -1
  106. package/lib/typescript/src/usePreventRemove.d.ts.map +1 -1
  107. package/lib/typescript/src/usePreventRemoveContext.d.ts +1 -0
  108. package/lib/typescript/src/usePreventRemoveContext.d.ts.map +1 -1
  109. package/lib/typescript/src/useRoute.d.ts +1 -1
  110. package/lib/typescript/src/useRoute.d.ts.map +1 -1
  111. package/lib/typescript/src/useRouteCache.d.ts.map +1 -1
  112. package/lib/typescript/src/useScheduleUpdate.d.ts +5 -4
  113. package/lib/typescript/src/useScheduleUpdate.d.ts.map +1 -1
  114. package/lib/typescript/src/useSyncState.d.ts.map +1 -1
  115. package/lib/typescript/src/utilities.d.ts +21 -38
  116. package/lib/typescript/src/utilities.d.ts.map +1 -1
  117. package/lib/typescript/src/validatePathConfig.d.ts.map +1 -1
  118. package/package.json +6 -8
  119. package/src/BaseNavigationContainer.tsx +9 -2
  120. package/src/DataLoading.tsx +139 -0
  121. package/src/NavigationBuilderContext.tsx +5 -1
  122. package/src/NavigationIndependentTree.tsx +11 -11
  123. package/src/NavigationProvider.tsx +13 -16
  124. package/src/PreventRemoveContext.tsx +1 -0
  125. package/src/PreventRemoveProvider.tsx +48 -43
  126. package/src/StaticNavigation.tsx +164 -99
  127. package/src/StaticTreeContext.tsx +7 -0
  128. package/src/checkSerializable.tsx +20 -14
  129. package/src/createNavigationContainerRef.tsx +12 -9
  130. package/src/createNavigatorFactory.tsx +27 -18
  131. package/src/getActionFromState.tsx +18 -16
  132. package/src/getPathFromState.tsx +167 -132
  133. package/src/getPatternParts.tsx +2 -2
  134. package/src/getStateFromPath.tsx +260 -193
  135. package/src/index.tsx +3 -0
  136. package/src/types.tsx +298 -62
  137. package/src/useEventEmitter.tsx +7 -2
  138. package/src/useKeyedChildListeners.tsx +4 -2
  139. package/src/useNavigation.tsx +2 -21
  140. package/src/useNavigationBuilder.tsx +7 -24
  141. package/src/useNavigationCache.tsx +26 -19
  142. package/src/useNavigationHelpers.tsx +26 -9
  143. package/src/useNavigationState.tsx +90 -60
  144. package/src/useOnAction.tsx +55 -3
  145. package/src/useOnPreventRemove.tsx +68 -36
  146. package/src/useOptionsGetters.tsx +4 -1
  147. package/src/usePreventRemove.tsx +11 -2
  148. package/src/useRoute.tsx +3 -5
  149. package/src/useRouteCache.tsx +19 -11
  150. package/src/useScheduleUpdate.tsx +8 -7
  151. package/src/useSyncState.tsx +5 -1
  152. package/src/utilities.tsx +36 -41
  153. package/src/validatePathConfig.tsx +86 -58
@@ -1 +1 @@
1
- {"version":3,"file":"useRouteCache.d.ts","sourceRoot":"","sources":["../../../src/useRouteCache.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,2BAA2B,CAAC;AAQhF;;;;GAIG;AACH,eAAO,MAAM,WAAW,eAAwB,CAAC;AAEjD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,SAAS,eAAe,EACzD,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC;;;;;;;;;;KA+CxB"}
1
+ {"version":3,"file":"useRouteCache.d.ts","sourceRoot":"","sources":["../../../src/useRouteCache.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,2BAA2B,CAAC;AAMhF;;;;GAIG;AACH,eAAO,MAAM,WAAW,eAAwB,CAAC;AAEjD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,SAAS,eAAe,EACzD,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC;;;;;;;;;;KAyDxB"}
@@ -1,9 +1,10 @@
1
1
  /**
2
2
  * When screen config changes, we want to update the navigator in the same update phase.
3
- * However, navigation state is in the root component and React won't let us update it from a child.
4
- * This is a workaround for that, the scheduled update is stored in the ref without actually calling setState.
5
- * It lets all subsequent updates access the latest state so it stays correct.
6
- * Then we call setState during after the component updates.
3
+ * However, navigation state is in the root component and React won't let us update it from a child during render.
4
+ * The render could also be interrupted in concurrent mode, so we need to update after commit.
5
+ * So we queue the update in an insertion effect and flush it in a layout effect.
6
+ * Insertion effects run before layout effects, so every navigator in the tree has queued its update before we flush.
7
+ * This lets nested updates be applied from the root down without clobbering each other.
7
8
  */
8
9
  export declare function useScheduleUpdate(callback: () => void): void;
9
10
  //# sourceMappingURL=useScheduleUpdate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useScheduleUpdate.d.ts","sourceRoot":"","sources":["../../../src/useScheduleUpdate.tsx"],"names":[],"mappings":"AAIA;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,IAAI,QAQrD"}
1
+ {"version":3,"file":"useScheduleUpdate.d.ts","sourceRoot":"","sources":["../../../src/useScheduleUpdate.tsx"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,IAAI,QAQrD"}
@@ -1 +1 @@
1
- {"version":3,"file":"useSyncState.d.ts","sourceRoot":"","sources":["../../../src/useSyncState.tsx"],"names":[],"mappings":"AA8DA,wBAAgB,YAAY,CAAC,CAAC,EAAE,eAAe,EAAE,MAAM,CAAC;;;;wCA6BF,MAAM,IAAI;;EA4B/D"}
1
+ {"version":3,"file":"useSyncState.d.ts","sourceRoot":"","sources":["../../../src/useSyncState.tsx"],"names":[],"mappings":"AA8DA,wBAAgB,YAAY,CAAC,CAAC,EAAE,eAAe,EAAE,MAAM,CAAC;;;;wCA6BF,MAAM,IAAI;;EAgC/D"}
@@ -14,12 +14,18 @@ export type KeysOf<T> = T extends {} ? keyof T : never;
14
14
  * Extract string keys from an object type.
15
15
  */
16
16
  export type KeyOf<T extends {}> = Extract<keyof T, string>;
17
+ /**
18
+ * TS only checks object literals for excess properties when they are not generic.
19
+ * When an object is captured as a generic type, unknown keys are not caught.
20
+ * This builds a type from the provided object where any key not in the allowed type has the type `never`.
21
+ * Checking the provided object against this type then produces an error for each unknown key.
22
+ */
23
+ export type NoExcessObject<Provided, Allowed> = Record<Exclude<keyof Provided, keyof Allowed>, never>;
17
24
  /**
18
25
  * We get a union type when using keyof, but we want an intersection instead.
19
26
  * https://stackoverflow.com/a/50375286/1665026
20
27
  */
21
28
  export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
22
- export type UnknownToUndefined<T> = unknown extends T ? undefined : T;
23
29
  /**
24
30
  * Exclude undefined from a type.
25
31
  * Similar to NonNullable but only excludes undefined, not null.
@@ -29,6 +35,16 @@ export type AnyToUnknown<T> = 0 extends 1 & T ? unknown : T;
29
35
  export type RequiredKeys<T extends object> = {
30
36
  [K in keyof T]-?: {} extends Pick<T, K> ? never : K;
31
37
  }[keyof T];
38
+ type OptionalKeys<T extends object> = Exclude<keyof T, RequiredKeys<T>>;
39
+ /**
40
+ * Remove `| undefined` from the object type,
41
+ * and adjust the optionality of the keys based on the original type.
42
+ */
43
+ export type NotUndefinedObject<T extends object | undefined, O extends object = NotUndefined<T>> = undefined extends T ? {
44
+ [K in RequiredKeys<O>]: O[K];
45
+ } & {
46
+ [K in OptionalKeys<O>]?: O[K] | undefined;
47
+ } : T;
32
48
  export type UndefinedIfAllOptional<T> = T extends object ? RequiredKeys<T> extends never ? T | undefined : T : T;
33
49
  /**
34
50
  * Check if a function type has arguments.
@@ -96,44 +112,11 @@ type QueryParamOptionalKeys<Params, Parse> = {
96
112
  * It doesn't include parse functions (as they are always optional)
97
113
  */
98
114
  type QueryParamRequiredKeys<Params, Parse> = Exclude<Exclude<keyof Parse, keyof Params>, QueryParamOptionalKeys<Params, Parse>>;
99
- /**
100
- * Infer the path string from a linking config.
101
- */
102
- export type InferPath<T> = T extends {
103
- path: infer P extends string;
104
- } ? P : never;
105
- /**
106
- * Infer the parse functions from a linking config.
107
- */
108
- export type InferParse<T> = T extends {
109
- parse: infer P;
110
- } ? P : {};
111
115
  export type InferParamsFromLinking<T> = T extends {
112
116
  path: infer P extends string;
113
- } ? UndefinedIfAllOptional<ExtractParamsType<ExtractParamStrings<P>, InferParse<T>>> : T extends string ? UndefinedIfAllOptional<ExtractParamsType<ExtractParamStrings<T>, undefined>> : undefined;
114
- /**
115
- * Infer the params type from a screen component or nested navigator.
116
- */
117
- export type InferScreenParams<T> = T extends React.ComponentType<{
118
- route: {
119
- params: infer P;
120
- };
121
- }> ? P : T extends {
122
- config: {
123
- screens: infer Screens;
124
- };
125
- } ? import('./types.js').NavigatorScreenParams<{
126
- [K in keyof Screens]: Screens[K] extends React.ComponentType<{
127
- route: {
128
- params: infer P;
129
- };
130
- }> ? P : Screens[K] extends {
131
- screen: infer S;
132
- } ? S extends React.ComponentType<{
133
- route: {
134
- params: infer P;
135
- };
136
- }> ? P : undefined : undefined;
137
- }> : undefined;
117
+ parse: infer Parse;
118
+ } ? UndefinedIfAllOptional<ExtractParamsType<ExtractParamStrings<P>, Parse>> : T extends {
119
+ path: infer P extends string;
120
+ } ? UndefinedIfAllOptional<ExtractParamStrings<P>> : T extends string ? UndefinedIfAllOptional<ExtractParamStrings<T>> : undefined;
138
121
  export {};
139
122
  //# sourceMappingURL=utilities.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../../src/utilities.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../../src/utilities.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"validatePathConfig.d.ts","sourceRoot":"","sources":["../../../src/validatePathConfig.tsx"],"names":[],"mappings":"AAKA,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,UAAO,QA8E9D"}
1
+ {"version":3,"file":"validatePathConfig.d.ts","sourceRoot":"","sources":["../../../src/validatePathConfig.tsx"],"names":[],"mappings":"AAmCA,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,UAAO,QA4E9D"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@react-navigation/core",
3
3
  "description": "Core utilities for building navigators",
4
- "version": "8.0.0-alpha.23",
4
+ "version": "8.0.0-alpha.25",
5
5
  "keywords": [
6
6
  "react",
7
7
  "react-native",
@@ -21,7 +21,7 @@
21
21
  "types": "./lib/typescript/src/index.d.ts",
22
22
  "exports": {
23
23
  ".": {
24
- "source": "./src/index.tsx",
24
+ "@react-navigation/source": "./src/index.tsx",
25
25
  "types": "./lib/typescript/src/index.d.ts",
26
26
  "default": "./lib/module/index.js"
27
27
  },
@@ -40,26 +40,24 @@
40
40
  "clean": "del lib"
41
41
  },
42
42
  "dependencies": {
43
- "@react-navigation/routers": "^8.0.0-alpha.12",
43
+ "@react-navigation/routers": "^8.0.0-alpha.13",
44
44
  "escape-string-regexp": "^5.0.0",
45
45
  "fast-deep-equal": "^3.1.3",
46
46
  "nanoid": "^5.1.11",
47
47
  "query-string": "^9.4.0",
48
48
  "react-is": "^19.2.6",
49
- "use-latest-callback": "^0.3.4",
50
- "use-sync-external-store": "^1.6.0"
49
+ "use-latest-callback": "^0.3.4"
51
50
  },
52
51
  "devDependencies": {
53
52
  "@jest/globals": "^29.7.0",
54
53
  "@testing-library/react-native": "^14.0.0",
55
54
  "@types/react": "~19.2.17",
56
55
  "@types/react-is": "^19.2.0",
57
- "@types/use-sync-external-store": "^1.5.0",
58
56
  "del-cli": "^7.0.0",
59
57
  "immer": "^11.1.8",
60
58
  "react": "19.2.0",
61
59
  "react-native": "0.83.6",
62
- "react-native-builder-bob": "^0.42.1",
60
+ "react-native-builder-bob": "^0.43.0",
63
61
  "test-renderer": "1.2.0",
64
62
  "typescript": "^6.0.3",
65
63
  "valibot": "^1.4.1",
@@ -86,5 +84,5 @@
86
84
  ]
87
85
  ]
88
86
  },
89
- "gitHead": "b18e1874297bb41bb0dc048b25b4dbc02cb5af50"
87
+ "gitHead": "7e0376c860594b1c33543a6fab508165919f15a7"
90
88
  }
@@ -125,10 +125,16 @@ export function BaseNavigationContainer<ParamList extends {} = RootParamList>({
125
125
  (
126
126
  action: NavigationAction | ((state: NavigationState) => NavigationAction)
127
127
  ) => {
128
- if (listeners.focus[0] == null) {
128
+ const listener = listeners.focus[0];
129
+
130
+ if (listener == null) {
129
131
  console.error(NOT_INITIALIZED_ERROR);
130
132
  } else {
131
- listeners.focus[0]((navigation) => navigation.dispatch(action));
133
+ listener((navigation) =>
134
+ React.startTransition(() => {
135
+ navigation.dispatch(action);
136
+ })
137
+ );
132
138
  }
133
139
  }
134
140
  );
@@ -195,6 +201,7 @@ export function BaseNavigationContainer<ParamList extends {} = RootParamList>({
195
201
  acc[name] = (...args: any[]) =>
196
202
  // @ts-expect-error: this is ok
197
203
  dispatch(CommonActions[name](...args));
204
+
198
205
  return acc;
199
206
  }, {}),
200
207
  ...emitter.create('root'),
@@ -0,0 +1,139 @@
1
+ import type { NavigationState, PartialState } from '@react-navigation/routers';
2
+
3
+ import { getStateFromRouteParams } from './getStateFromRouteParams';
4
+ import type { TreeForPathConfig } from './StaticNavigation';
5
+
6
+ function findScreenInConfig(config: TreeForPathConfig['config'], name: string) {
7
+ const screens = config.screens;
8
+
9
+ if (screens?.[name] != null) {
10
+ return screens[name];
11
+ }
12
+
13
+ if (config.groups) {
14
+ for (const group of Object.values(config.groups)) {
15
+ if (group.screens[name] != null) {
16
+ return group.screens[name];
17
+ }
18
+ }
19
+ }
20
+
21
+ return undefined;
22
+ }
23
+
24
+ function findInitialRouteName(
25
+ config: TreeForPathConfig['config']
26
+ ): string | undefined {
27
+ if (config.initialRouteName != null) {
28
+ return config.initialRouteName;
29
+ }
30
+
31
+ for (const key in config) {
32
+ if (key === 'screens' && config.screens) {
33
+ const name = Object.keys(config.screens)[0];
34
+
35
+ if (name != null) {
36
+ return name;
37
+ }
38
+ }
39
+
40
+ if (key === 'groups' && config.groups) {
41
+ for (const group of Object.values(config.groups)) {
42
+ const name = Object.keys(group.screens)[0];
43
+
44
+ if (name != null) {
45
+ return name;
46
+ }
47
+ }
48
+ }
49
+ }
50
+
51
+ return undefined;
52
+ }
53
+
54
+ /**
55
+ * Get loader for the focused route in a static config tree with given navigation state.
56
+ *
57
+ * @param tree The static navigation config.
58
+ * @param state The navigation state to extract the focused route path from.
59
+ * @returns A function that returns a `Promise<void>`, or `undefined` if no loaders are found.
60
+ *
61
+ * @example
62
+ * ```js
63
+ * const loader = getLoaderForState(RootStack, {
64
+ * index: 0,
65
+ * routes: [{ name: 'Home' }],
66
+ * });
67
+ * await loader?.();
68
+ * ```
69
+ */
70
+ export function getLoaderForState(
71
+ tree: TreeForPathConfig,
72
+ state: PartialState<NavigationState> | NavigationState | undefined
73
+ ): (() => Promise<void>) | undefined {
74
+ const focusedRoute = state?.routes[state.index ?? 0];
75
+
76
+ if (!focusedRoute) {
77
+ return undefined;
78
+ }
79
+
80
+ const item = findScreenInConfig(tree.config, focusedRoute.name);
81
+
82
+ if (item == null) {
83
+ return undefined;
84
+ }
85
+
86
+ const initialParams =
87
+ typeof item === 'object' && 'initialParams' in item
88
+ ? item.initialParams
89
+ : undefined;
90
+
91
+ const params =
92
+ initialParams != null || focusedRoute.params != null
93
+ ? { ...initialParams, ...focusedRoute.params }
94
+ : undefined;
95
+
96
+ const loaders: (() => Promise<void>)[] = [];
97
+
98
+ if ('UNSTABLE_loader' in item && typeof item.UNSTABLE_loader === 'function') {
99
+ const loader = item.UNSTABLE_loader;
100
+
101
+ loaders.push(() =>
102
+ loader({
103
+ name: focusedRoute.name,
104
+ params,
105
+ })
106
+ );
107
+ }
108
+
109
+ const nested =
110
+ 'config' in item
111
+ ? item
112
+ : 'screen' in item && 'config' in item.screen
113
+ ? item.screen
114
+ : undefined;
115
+
116
+ if (nested) {
117
+ const initialRouteName = findInitialRouteName(nested.config);
118
+
119
+ let childState = focusedRoute.state ?? getStateFromRouteParams(params);
120
+
121
+ if (childState == null && initialRouteName != null) {
122
+ childState = { routes: [{ name: initialRouteName }] };
123
+ }
124
+
125
+ const childLoader = getLoaderForState(nested, childState);
126
+
127
+ if (childLoader) {
128
+ loaders.push(childLoader);
129
+ }
130
+ }
131
+
132
+ if (loaders.length === 0) {
133
+ return undefined;
134
+ }
135
+
136
+ return async () => {
137
+ await Promise.all(loaders.map((l) => l()));
138
+ };
139
+ }
@@ -2,6 +2,7 @@ import type {
2
2
  NavigationAction,
3
3
  NavigationState,
4
4
  ParamListBase,
5
+ PartialState,
5
6
  } from '@react-navigation/routers';
6
7
  import * as React from 'react';
7
8
 
@@ -46,7 +47,10 @@ export type FocusedNavigationListener = <T>(
46
47
 
47
48
  export type GetStateListener = () => NavigationState;
48
49
 
49
- export type ChildBeforeRemoveListener = (action: NavigationAction) => boolean;
50
+ export type ChildBeforeRemoveListener = (
51
+ action: NavigationAction,
52
+ nextState: NavigationState | PartialState<NavigationState> | undefined
53
+ ) => boolean;
50
54
 
51
55
  /**
52
56
  * Context which holds the required helpers needed to build nested navigators.
@@ -5,9 +5,9 @@ import {
5
5
  NamedRouteContextListContext,
6
6
  NavigationContext,
7
7
  NavigationRouteContext,
8
- NavigationRouteNameContext,
9
8
  } from './NavigationProvider';
10
9
  import { IsFocusedContext } from './useIsFocused';
10
+ import { NamedNavigationStateListenerListContext } from './useNavigationState';
11
11
 
12
12
  /**
13
13
  * Component to make the child navigation container independent of parent containers.
@@ -19,18 +19,18 @@ export function NavigationIndependentTree({
19
19
  }) {
20
20
  return (
21
21
  // We need to clear any existing contexts for nested independent container to work correctly
22
- <NamedRouteContextListContext.Provider value={undefined}>
23
- <NavigationRouteContext.Provider value={undefined}>
24
- <NavigationContext.Provider value={undefined}>
25
- <IsFocusedContext.Provider value={undefined}>
26
- <NavigationRouteNameContext.Provider value={undefined}>
22
+ <NamedNavigationStateListenerListContext.Provider value={undefined}>
23
+ <NamedRouteContextListContext.Provider value={undefined}>
24
+ <NavigationRouteContext.Provider value={undefined}>
25
+ <NavigationContext.Provider value={undefined}>
26
+ <IsFocusedContext.Provider value={undefined}>
27
27
  <NavigationIndependentTreeContext.Provider value={true}>
28
28
  {children}
29
29
  </NavigationIndependentTreeContext.Provider>
30
- </NavigationRouteNameContext.Provider>
31
- </IsFocusedContext.Provider>
32
- </NavigationContext.Provider>
33
- </NavigationRouteContext.Provider>
34
- </NamedRouteContextListContext.Provider>
30
+ </IsFocusedContext.Provider>
31
+ </NavigationContext.Provider>
32
+ </NavigationRouteContext.Provider>
33
+ </NamedRouteContextListContext.Provider>
34
+ </NamedNavigationStateListenerListContext.Provider>
35
35
  );
36
36
  }
@@ -4,6 +4,7 @@ import * as React from 'react';
4
4
  import type { NavigationProp } from './types';
5
5
  import { FocusedRouteKeyContext, IsFocusedContext } from './useIsFocused';
6
6
  import { useLazyValue } from './useLazyValue';
7
+ import { NamedNavigationStateListenerProvider } from './useNavigationState';
7
8
 
8
9
  /**
9
10
  * Context which holds the route prop for a screen.
@@ -19,10 +20,6 @@ export const NavigationContext = React.createContext<
19
20
  NavigationProp<ParamListBase> | undefined
20
21
  >(undefined);
21
22
 
22
- export const NavigationRouteNameContext = React.createContext<
23
- string | undefined
24
- >(undefined);
25
-
26
23
  type Props = {
27
24
  route: Route<string>;
28
25
  navigation: NavigationProp<ParamListBase>;
@@ -61,18 +58,18 @@ export function NavigationProvider({ route, navigation, children }: Props) {
61
58
  : false;
62
59
 
63
60
  return (
64
- <NamedRouteContextListContext.Provider value={NamedRouteContextList}>
65
- <NamedRouteContext.Provider value={route}>
66
- <NavigationRouteContext.Provider value={route}>
67
- <NavigationContext.Provider value={navigation}>
68
- <IsFocusedContext.Provider value={isFocused}>
69
- <NavigationRouteNameContext.Provider value={route.name}>
61
+ <NamedNavigationStateListenerProvider name={route.name}>
62
+ <NamedRouteContextListContext.Provider value={NamedRouteContextList}>
63
+ <NamedRouteContext.Provider value={route}>
64
+ <NavigationRouteContext.Provider value={route}>
65
+ <NavigationContext.Provider value={navigation}>
66
+ <IsFocusedContext.Provider value={isFocused}>
70
67
  {children}
71
- </NavigationRouteNameContext.Provider>
72
- </IsFocusedContext.Provider>
73
- </NavigationContext.Provider>
74
- </NavigationRouteContext.Provider>
75
- </NamedRouteContext.Provider>
76
- </NamedRouteContextListContext.Provider>
68
+ </IsFocusedContext.Provider>
69
+ </NavigationContext.Provider>
70
+ </NavigationRouteContext.Provider>
71
+ </NamedRouteContext.Provider>
72
+ </NamedRouteContextListContext.Provider>
73
+ </NamedNavigationStateListenerProvider>
77
74
  );
78
75
  }
@@ -14,6 +14,7 @@ export const PreventRemoveContext = React.createContext<
14
14
  routeKey: string,
15
15
  preventRemove: boolean
16
16
  ) => void;
17
+ notifyPreventRemove: () => void;
17
18
  }
18
19
  | undefined
19
20
  >(undefined);
@@ -13,13 +13,7 @@ type Props = {
13
13
  children: React.ReactNode;
14
14
  };
15
15
 
16
- type PreventedRoutesMap = Map<
17
- string,
18
- {
19
- routeKey: string;
20
- preventRemove: boolean;
21
- }
22
- >;
16
+ type PreventedRoutesMap = Map<string, string>;
23
17
 
24
18
  /**
25
19
  * Util function to transform map of prevented routes to a simpler object.
@@ -27,17 +21,11 @@ type PreventedRoutesMap = Map<
27
21
  const transformPreventedRoutes = (
28
22
  preventedRoutesMap: PreventedRoutesMap
29
23
  ): PreventedRoutes => {
30
- const preventedRoutesToTransform = [...preventedRoutesMap.values()];
24
+ const preventedRoutes: PreventedRoutes = {};
31
25
 
32
- const preventedRoutes = preventedRoutesToTransform.reduce<PreventedRoutes>(
33
- (acc, { routeKey, preventRemove }) => {
34
- acc[routeKey] = {
35
- preventRemove: acc[routeKey]?.preventRemove || preventRemove,
36
- };
37
- return acc;
38
- },
39
- {}
40
- );
26
+ for (const routeKey of preventedRoutesMap.values()) {
27
+ preventedRoutes[routeKey] = { preventRemove: true };
28
+ }
41
29
 
42
30
  return preventedRoutes;
43
31
  };
@@ -50,12 +38,15 @@ export function PreventRemoveProvider({ children }: Props) {
50
38
  const [preventedRoutesMap, setPreventedRoutesMap] =
51
39
  React.useState<PreventedRoutesMap>(() => new Map());
52
40
 
41
+ const registry = React.useRef<PreventedRoutesMap>(new Map());
42
+
53
43
  const navigation = React.use(NavigationHelpersContext);
54
44
  const route = React.use(NavigationRouteContext);
55
45
 
56
46
  const preventRemoveContextValue = React.use(PreventRemoveContext);
57
47
  // take `setPreventRemove` from parent context - if exist it means we're in a nested context
58
48
  const setParentPrevented = preventRemoveContextValue?.setPreventRemove;
49
+ const notifyParentPrevented = preventRemoveContextValue?.notifyPreventRemove;
59
50
 
60
51
  const setPreventRemove = useLatestCallback(
61
52
  (id: string, routeKey: string, preventRemove: boolean): void => {
@@ -71,36 +62,49 @@ export function PreventRemoveProvider({ children }: Props) {
71
62
  );
72
63
  }
73
64
 
74
- setPreventedRoutesMap((prevPrevented) => {
75
- // values haven't changed - do nothing
76
- if (
77
- routeKey === prevPrevented.get(id)?.routeKey &&
78
- preventRemove === prevPrevented.get(id)?.preventRemove
79
- ) {
80
- return prevPrevented;
81
- }
82
-
83
- const nextPrevented = new Map(prevPrevented);
84
-
85
- if (preventRemove) {
86
- nextPrevented.set(id, {
87
- routeKey,
88
- preventRemove,
89
- });
90
- } else {
91
- nextPrevented.delete(id);
92
- }
93
-
94
- return nextPrevented;
95
- });
65
+ if (preventRemove) {
66
+ registry.current.set(id, routeKey);
67
+ } else {
68
+ registry.current.delete(id);
69
+ }
96
70
  }
97
71
  );
98
72
 
99
- const isPrevented = [...preventedRoutesMap.values()].some(
100
- ({ preventRemove }) => preventRemove
101
- );
73
+ const notifyPreventRemove = useLatestCallback(() => {
74
+ // eslint-disable-next-line @eslint-react/hooks-extra/no-direct-set-state-in-use-effect
75
+ setPreventedRoutesMap((prevPrevented) => {
76
+ const nextPrevented = registry.current;
102
77
 
78
+ const hasChanged =
79
+ prevPrevented.size !== nextPrevented.size ||
80
+ [...nextPrevented].some(
81
+ ([id, routeKey]) => prevPrevented.get(id) !== routeKey
82
+ );
83
+
84
+ // values haven't changed - do nothing
85
+ if (!hasChanged) {
86
+ return prevPrevented;
87
+ }
88
+
89
+ return new Map(nextPrevented);
90
+ });
91
+ });
92
+
93
+ // Sync the state on every commit in case the registry was changed by a screen
94
+ // unmounting while hidden with `<Activity>`, where no passive effects run
95
+ // Also notify the parent so nested prevention propagates upwards
103
96
  React.useEffect(() => {
97
+ notifyPreventRemove();
98
+ notifyParentPrevented?.();
99
+
100
+ return () => {
101
+ notifyParentPrevented?.();
102
+ };
103
+ });
104
+
105
+ const isPrevented = preventedRoutesMap.size > 0;
106
+
107
+ React.useInsertionEffect(() => {
104
108
  if (route?.key !== undefined && setParentPrevented !== undefined) {
105
109
  // when route is defined (and setParentPrevented) it means we're in a nested stack
106
110
  // route.key then will be the route key of parent
@@ -116,9 +120,10 @@ export function PreventRemoveProvider({ children }: Props) {
116
120
  const value = React.useMemo(
117
121
  () => ({
118
122
  setPreventRemove,
123
+ notifyPreventRemove,
119
124
  preventedRoutes: transformPreventedRoutes(preventedRoutesMap),
120
125
  }),
121
- [setPreventRemove, preventedRoutesMap]
126
+ [setPreventRemove, notifyPreventRemove, preventedRoutesMap]
122
127
  );
123
128
 
124
129
  return (