@react-navigation/core 7.22.1 → 7.24.0

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 (95) hide show
  1. package/lib/module/BaseNavigationContainer.js +50 -22
  2. package/lib/module/BaseNavigationContainer.js.map +1 -1
  3. package/lib/module/NavigationBuilderContext.js +7 -11
  4. package/lib/module/NavigationBuilderContext.js.map +1 -1
  5. package/lib/module/NavigationIndependentTree.js +41 -10
  6. package/lib/module/NavigationIndependentTree.js.map +1 -1
  7. package/lib/module/NavigationMetaContext.js +3 -3
  8. package/lib/module/NavigationProvider.js +2 -2
  9. package/lib/module/NavigationProvider.js.map +1 -1
  10. package/lib/module/NavigationStateContext.js.map +1 -1
  11. package/lib/module/PreventRemoveProvider.js +3 -4
  12. package/lib/module/PreventRemoveProvider.js.map +1 -1
  13. package/lib/module/SceneView.js +18 -16
  14. package/lib/module/SceneView.js.map +1 -1
  15. package/lib/module/StaticNavigation.js +53 -18
  16. package/lib/module/StaticNavigation.js.map +1 -1
  17. package/lib/module/isRecordEqual.js +1 -1
  18. package/lib/module/isRecordEqual.js.map +1 -1
  19. package/lib/module/useDescriptors.js +40 -15
  20. package/lib/module/useDescriptors.js.map +1 -1
  21. package/lib/module/useFocusedListenersChildrenAdapter.js +2 -2
  22. package/lib/module/useFocusedListenersChildrenAdapter.js.map +1 -1
  23. package/lib/module/useNavigationBuilder.js +3 -2
  24. package/lib/module/useNavigationBuilder.js.map +1 -1
  25. package/lib/module/useNavigationCache.js +14 -26
  26. package/lib/module/useNavigationCache.js.map +1 -1
  27. package/lib/module/useNavigationHelpers.js +17 -7
  28. package/lib/module/useNavigationHelpers.js.map +1 -1
  29. package/lib/module/useNavigationState.js +1 -1
  30. package/lib/module/useNavigationState.js.map +1 -1
  31. package/lib/module/useOnAction.js +2 -2
  32. package/lib/module/useOnAction.js.map +1 -1
  33. package/lib/module/useOnGetState.js +2 -2
  34. package/lib/module/useOnGetState.js.map +1 -1
  35. package/lib/module/useOnPreventRemove.js +2 -2
  36. package/lib/module/useOnPreventRemove.js.map +1 -1
  37. package/lib/module/useOnRouteFocus.js +2 -2
  38. package/lib/module/useOnRouteFocus.js.map +1 -1
  39. package/lib/module/useOptionsGetters.js +4 -8
  40. package/lib/module/useOptionsGetters.js.map +1 -1
  41. package/lib/module/usePreventRemove.js +1 -2
  42. package/lib/module/usePreventRemove.js.map +1 -1
  43. package/lib/module/useRegisterNavigator.js +1 -2
  44. package/lib/module/useRegisterNavigator.js.map +1 -1
  45. package/lib/module/useScheduleUpdate.js +2 -2
  46. package/lib/module/useScheduleUpdate.js.map +1 -1
  47. package/lib/typescript/src/BaseNavigationContainer.d.ts.map +1 -1
  48. package/lib/typescript/src/NavigationBuilderContext.d.ts +11 -7
  49. package/lib/typescript/src/NavigationBuilderContext.d.ts.map +1 -1
  50. package/lib/typescript/src/NavigationIndependentTree.d.ts.map +1 -1
  51. package/lib/typescript/src/NavigationMetaContext.d.ts +3 -3
  52. package/lib/typescript/src/NavigationProvider.d.ts.map +1 -1
  53. package/lib/typescript/src/NavigationStateContext.d.ts +0 -1
  54. package/lib/typescript/src/NavigationStateContext.d.ts.map +1 -1
  55. package/lib/typescript/src/PreventRemoveProvider.d.ts.map +1 -1
  56. package/lib/typescript/src/SceneView.d.ts.map +1 -1
  57. package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
  58. package/lib/typescript/src/isRecordEqual.d.ts.map +1 -1
  59. package/lib/typescript/src/useDescriptors.d.ts.map +1 -1
  60. package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
  61. package/lib/typescript/src/useNavigationCache.d.ts.map +1 -1
  62. package/lib/typescript/src/useNavigationHelpers.d.ts.map +1 -1
  63. package/lib/typescript/src/useNavigationState.d.ts +5 -0
  64. package/lib/typescript/src/useNavigationState.d.ts.map +1 -1
  65. package/lib/typescript/src/useOnRouteFocus.d.ts.map +1 -1
  66. package/lib/typescript/src/useOptionsGetters.d.ts +2 -0
  67. package/lib/typescript/src/useOptionsGetters.d.ts.map +1 -1
  68. package/lib/typescript/src/usePreventRemove.d.ts.map +1 -1
  69. package/lib/typescript/src/useRegisterNavigator.d.ts.map +1 -1
  70. package/lib/typescript/src/useScheduleUpdate.d.ts.map +1 -1
  71. package/package.json +3 -4
  72. package/src/BaseNavigationContainer.tsx +73 -33
  73. package/src/NavigationBuilderContext.tsx +27 -17
  74. package/src/NavigationIndependentTree.tsx +41 -13
  75. package/src/NavigationMetaContext.tsx +3 -3
  76. package/src/NavigationProvider.tsx +11 -8
  77. package/src/NavigationStateContext.tsx +0 -4
  78. package/src/PreventRemoveProvider.tsx +4 -10
  79. package/src/SceneView.tsx +18 -25
  80. package/src/StaticNavigation.tsx +71 -17
  81. package/src/isRecordEqual.tsx +3 -1
  82. package/src/useDescriptors.tsx +99 -27
  83. package/src/useFocusedListenersChildrenAdapter.tsx +2 -2
  84. package/src/useNavigationBuilder.tsx +3 -4
  85. package/src/useNavigationCache.tsx +13 -30
  86. package/src/useNavigationHelpers.tsx +18 -6
  87. package/src/useNavigationState.tsx +1 -1
  88. package/src/useOnAction.tsx +2 -2
  89. package/src/useOnGetState.tsx +2 -2
  90. package/src/useOnPreventRemove.tsx +2 -2
  91. package/src/useOnRouteFocus.tsx +2 -4
  92. package/src/useOptionsGetters.tsx +9 -6
  93. package/src/usePreventRemove.tsx +1 -2
  94. package/src/useRegisterNavigator.tsx +2 -2
  95. package/src/useScheduleUpdate.tsx +2 -4
@@ -1 +1 @@
1
- {"version":3,"file":"useNavigationState.d.ts","sourceRoot":"","sources":["../../../src/useNavigationState.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAU/B,KAAK,QAAQ,CAAC,SAAS,SAAS,aAAa,EAAE,CAAC,IAAI,CAClD,KAAK,EAAE,eAAe,CAAC,SAAS,CAAC,KAC9B,CAAC,CAAC;AAEP;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,SAAS,aAAa,EAAE,CAAC,EACnE,QAAQ,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,GAC/B,CAAC,CA+CH;AAED,wBAAgB,+BAA+B,CAAC,EAC9C,KAAK,EACL,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,eAAe,CAAC,aAAa,CAAC,CAAC;IACtC,QAAQ,EAAE,MAAM,eAAe,CAAC,aAAa,CAAC,CAAC;IAC/C,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,qBA6BA"}
1
+ {"version":3,"file":"useNavigationState.d.ts","sourceRoot":"","sources":["../../../src/useNavigationState.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,KAAK,uBAAuB,GAAG;IAC7B,QAAQ,EAAE,MAAM,eAAe,CAAC,aAAa,CAAC,CAAC;IAC/C,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;CACjD,CAAC;AAEF,KAAK,QAAQ,CAAC,SAAS,SAAS,aAAa,EAAE,CAAC,IAAI,CAClD,KAAK,EAAE,eAAe,CAAC,SAAS,CAAC,KAC9B,CAAC,CAAC;AAEP;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,SAAS,aAAa,EAAE,CAAC,EACnE,QAAQ,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,GAC/B,CAAC,CA+CH;AAED,wBAAgB,+BAA+B,CAAC,EAC9C,KAAK,EACL,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,eAAe,CAAC,aAAa,CAAC,CAAC;IACtC,QAAQ,EAAE,MAAM,eAAe,CAAC,aAAa,CAAC,CAAC;IAC/C,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,qBA6BA;AAED,eAAO,MAAM,8BAA8B,oDAE/B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useOnRouteFocus.d.ts","sourceRoot":"","sources":["../../../src/useOnRouteFocus.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,MAAM,EACP,MAAM,2BAA2B,CAAC;AAKnC,KAAK,OAAO,CAAC,KAAK,SAAS,eAAe,EAAE,MAAM,SAAS,gBAAgB,IAAI;IAC7E,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC9B,QAAQ,EAAE,MAAM,KAAK,CAAC;IACtB,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,KAAK,SAAS,eAAe,EAC7B,MAAM,SAAS,gBAAgB,EAC/B,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,SAMnE,MAAM,UAcf"}
1
+ {"version":3,"file":"useOnRouteFocus.d.ts","sourceRoot":"","sources":["../../../src/useOnRouteFocus.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,MAAM,EACP,MAAM,2BAA2B,CAAC;AAKnC,KAAK,OAAO,CAAC,KAAK,SAAS,eAAe,EAAE,MAAM,SAAS,gBAAgB,IAAI;IAC7E,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC9B,QAAQ,EAAE,MAAM,KAAK,CAAC;IACtB,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,KAAK,SAAS,eAAe,EAC7B,MAAM,SAAS,gBAAgB,EAC/B,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,SAInE,MAAM,UAcf"}
@@ -1,5 +1,7 @@
1
1
  import type { ParamListBase } from '@react-navigation/routers';
2
+ import * as React from 'react';
2
3
  import type { NavigationProp } from './types.js';
4
+ export declare const OptionsGetterContext: React.Context<((key: string, getter: () => object | undefined | null) => void) | undefined>;
3
5
  type Options = {
4
6
  key?: string;
5
7
  navigation?: NavigationProp<ParamListBase>;
@@ -1 +1 @@
1
- {"version":3,"file":"useOptionsGetters.d.ts","sourceRoot":"","sources":["../../../src/useOptionsGetters.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAK/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAS,CAAC;AAE9C,KAAK,OAAO,GAAG;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC;IAC3C,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,OAAO;4BAkE7D,MAAM,UAAU,MAAM,MAAM,GAAG,SAAS,GAAG,IAAI;;EAiBxD"}
1
+ {"version":3,"file":"useOptionsGetters.d.ts","sourceRoot":"","sources":["../../../src/useOptionsGetters.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAS,CAAC;AAE9C,eAAO,MAAM,oBAAoB,uBACxB,MAAM,UAAU,MAAM,MAAM,GAAG,SAAS,GAAG,IAAI,KAAK,IAAI,cACrD,CAAC;AAEb,KAAK,OAAO,GAAG;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC;IAC3C,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,OAAO;4BAkE7D,MAAM,UAAU,MAAM,MAAM,GAAG,SAAS,GAAG,IAAI;;EAiBxD"}
@@ -1 +1 @@
1
- {"version":3,"file":"usePreventRemove.d.ts","sourceRoot":"","sources":["../../../src/usePreventRemove.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAUlE;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,OAAO,EACtB,QAAQ,EAAE,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE;QAAE,MAAM,EAAE,gBAAgB,CAAA;KAAE,CAAA;CAAE,KAAK,IAAI,QAyCpE"}
1
+ {"version":3,"file":"usePreventRemove.d.ts","sourceRoot":"","sources":["../../../src/usePreventRemove.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AASlE;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,OAAO,EACtB,QAAQ,EAAE,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE;QAAE,MAAM,EAAE,gBAAgB,CAAA;KAAE,CAAA;CAAE,KAAK,IAAI,QAyCpE"}
@@ -1 +1 @@
1
- {"version":3,"file":"useRegisterNavigator.d.ts","sourceRoot":"","sources":["../../../src/useRegisterNavigator.tsx"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAgB,oBAAoB,WAmBnC"}
1
+ {"version":3,"file":"useRegisterNavigator.d.ts","sourceRoot":"","sources":["../../../src/useRegisterNavigator.tsx"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,oBAAoB,WAoBnC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useScheduleUpdate.d.ts","sourceRoot":"","sources":["../../../src/useScheduleUpdate.tsx"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,IAAI,QAUrD"}
1
+ {"version":3,"file":"useScheduleUpdate.d.ts","sourceRoot":"","sources":["../../../src/useScheduleUpdate.tsx"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,IAAI,QAQrD"}
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": "7.22.1",
4
+ "version": "7.24.0",
5
5
  "keywords": [
6
6
  "react",
7
7
  "react-native",
@@ -40,10 +40,9 @@
40
40
  "clean": "del lib"
41
41
  },
42
42
  "dependencies": {
43
- "@react-navigation/routers": "^7.6.4",
43
+ "@react-navigation/routers": "^7.6.5",
44
44
  "escape-string-regexp": "^4.0.0",
45
45
  "fast-deep-equal": "^3.1.3",
46
- "nanoid": "^3.3.11",
47
46
  "react-is": "^19.1.0",
48
47
  "use-latest-callback": "^0.2.4",
49
48
  "use-sync-external-store": "^1.5.0"
@@ -82,5 +81,5 @@
82
81
  ]
83
82
  ]
84
83
  },
85
- "gitHead": "90950419c0ee5dec77cd40cee0687add80dcf625"
84
+ "gitHead": "379552aab1a143b61058ab572450cbfb363bff77"
86
85
  }
@@ -17,7 +17,10 @@ import { NOT_INITIALIZED_ERROR } from './createNavigationContainerRef';
17
17
  import { DeprecatedNavigationInChildContext } from './DeprecatedNavigationInChildContext';
18
18
  import { EnsureSingleNavigator } from './EnsureSingleNavigator';
19
19
  import { findFocusedRoute } from './findFocusedRoute';
20
- import { NavigationBuilderContext } from './NavigationBuilderContext';
20
+ import {
21
+ NavigationBuilderContext,
22
+ type WithStackTrace,
23
+ } from './NavigationBuilderContext';
21
24
  import { NavigationContainerRefContext } from './NavigationContainerRefContext';
22
25
  import { NavigationIndependentTreeContext } from './NavigationIndependentTreeContext';
23
26
  import { NavigationStateContext } from './NavigationStateContext';
@@ -33,7 +36,7 @@ import { useEventEmitter } from './useEventEmitter';
33
36
  import { useKeyedChildListeners } from './useKeyedChildListeners';
34
37
  import { useLazyValue } from './useLazyValue';
35
38
  import { useNavigationIndependentTree } from './useNavigationIndependentTree';
36
- import { useOptionsGetters } from './useOptionsGetters';
39
+ import { OptionsGetterContext, useOptionsGetters } from './useOptionsGetters';
37
40
  import { useSyncState } from './useSyncState';
38
41
 
39
42
  type State = NavigationState | PartialState<NavigationState> | undefined;
@@ -126,6 +129,41 @@ export const BaseNavigationContainer = React.forwardRef(
126
129
 
127
130
  const { keyedListeners, addKeyedListener } = useKeyedChildListeners();
128
131
 
132
+ const stackRef = React.useRef<string | undefined>(undefined);
133
+
134
+ const withStackTrace = React.useCallback<WithStackTrace>(
135
+ (entry, callback) => {
136
+ if (process.env.NODE_ENV === 'production' || stackRef.current != null) {
137
+ callback();
138
+ return;
139
+ }
140
+
141
+ const error = new Error();
142
+
143
+ if (Error.captureStackTrace) {
144
+ // Available on V8 and Hermes, omits the frames of `entry` and what it called
145
+ Error.captureStackTrace(error, entry);
146
+
147
+ stackRef.current = error.stack;
148
+ } else {
149
+ // Other engines always include them, so we drop the frames up to `entry` ourselves
150
+ const frames = error.stack?.split('\n') ?? [];
151
+ const index = frames.findIndex((frame) =>
152
+ frame.includes(`${entry.name}@`)
153
+ );
154
+
155
+ stackRef.current = frames.slice(index + 1).join('\n');
156
+ }
157
+
158
+ try {
159
+ callback();
160
+ } finally {
161
+ stackRef.current = undefined;
162
+ }
163
+ },
164
+ []
165
+ );
166
+
129
167
  const dispatch = useLatestCallback(
130
168
  (
131
169
  action:
@@ -135,7 +173,9 @@ export const BaseNavigationContainer = React.forwardRef(
135
173
  if (listeners.focus[0] == null) {
136
174
  console.error(NOT_INITIALIZED_ERROR);
137
175
  } else {
138
- listeners.focus[0]((navigation) => navigation.dispatch(action));
176
+ withStackTrace(dispatch, () => {
177
+ listeners.focus[0]((navigation) => navigation.dispatch(action));
178
+ });
139
179
  }
140
180
  }
141
181
  );
@@ -198,9 +238,14 @@ export const BaseNavigationContainer = React.forwardRef(
198
238
  const navigation: NavigationContainerRef<ParamListBase> = React.useMemo(
199
239
  () => ({
200
240
  ...Object.keys(CommonActions).reduce<any>((acc, name) => {
201
- acc[name] = (...args: any[]) =>
202
- // @ts-expect-error: this is ok
203
- dispatch(CommonActions[name](...args));
241
+ const helper = (...args: any[]) =>
242
+ withStackTrace(helper, () =>
243
+ // @ts-expect-error: this is ok
244
+ dispatch(CommonActions[name](...args))
245
+ );
246
+
247
+ acc[name] = helper;
248
+
204
249
  return acc;
205
250
  }, {}),
206
251
  ...emitter.create('root'),
@@ -228,6 +273,7 @@ export const BaseNavigationContainer = React.forwardRef(
228
273
  getState,
229
274
  isReady,
230
275
  resetRoot,
276
+ withStackTrace,
231
277
  ]
232
278
  );
233
279
 
@@ -266,8 +312,6 @@ export const BaseNavigationContainer = React.forwardRef(
266
312
  });
267
313
  });
268
314
 
269
- const stackRef = React.useRef<string | undefined>(undefined);
270
-
271
315
  const lastEmittedStateRef = React.useRef<State | undefined>(undefined);
272
316
 
273
317
  const getIsStateEmitted = useLatestCallback(
@@ -285,7 +329,7 @@ export const BaseNavigationContainer = React.forwardRef(
285
329
  getIsStateEmitted,
286
330
  scheduleUpdate,
287
331
  flushUpdates,
288
- stackRef,
332
+ withStackTrace,
289
333
  }),
290
334
  [
291
335
  addListener,
@@ -296,6 +340,7 @@ export const BaseNavigationContainer = React.forwardRef(
296
340
  getIsStateEmitted,
297
341
  scheduleUpdate,
298
342
  flushUpdates,
343
+ withStackTrace,
299
344
  ]
300
345
  );
301
346
 
@@ -311,17 +356,8 @@ export const BaseNavigationContainer = React.forwardRef(
311
356
  getKey,
312
357
  setKey,
313
358
  getIsInitial,
314
- addOptionsGetter,
315
359
  }),
316
- [
317
- state,
318
- getState,
319
- setState,
320
- getKey,
321
- setKey,
322
- getIsInitial,
323
- addOptionsGetter,
324
- ]
360
+ [state, getState, setState, getKey, setKey, getIsInitial]
325
361
  );
326
362
 
327
363
  const onReadyRef = React.useRef(onReady);
@@ -344,9 +380,9 @@ export const BaseNavigationContainer = React.forwardRef(
344
380
  }, [state, isReady, emitter]);
345
381
 
346
382
  React.useEffect(() => {
347
- const hydratedState = getRootState();
348
-
349
383
  if (process.env.NODE_ENV !== 'production') {
384
+ const hydratedState = getRootState();
385
+
350
386
  if (hydratedState !== undefined) {
351
387
  const serializableResult = checkSerializable(hydratedState);
352
388
 
@@ -418,6 +454,8 @@ export const BaseNavigationContainer = React.forwardRef(
418
454
  emitter.emit({ type: 'state', data: { state } });
419
455
 
420
456
  if (!isFirstMountRef.current && onStateChangeRef.current) {
457
+ const hydratedState = getRootState();
458
+
421
459
  onStateChangeRef.current(hydratedState);
422
460
  }
423
461
 
@@ -473,19 +511,21 @@ export const BaseNavigationContainer = React.forwardRef(
473
511
  <NavigationContainerRefContext.Provider value={navigation}>
474
512
  <NavigationBuilderContext.Provider value={builderContext}>
475
513
  <NavigationStateContext.Provider value={context}>
476
- <ConsumedParamsContext.Provider value={consumedParams}>
477
- <UnhandledActionContext.Provider
478
- value={onUnhandledAction ?? defaultOnUnhandledAction}
479
- >
480
- <DeprecatedNavigationInChildContext.Provider
481
- value={navigationInChildEnabled}
514
+ <OptionsGetterContext.Provider value={addOptionsGetter}>
515
+ <ConsumedParamsContext.Provider value={consumedParams}>
516
+ <UnhandledActionContext.Provider
517
+ value={onUnhandledAction ?? defaultOnUnhandledAction}
482
518
  >
483
- <EnsureSingleNavigator>
484
- <ThemeProvider value={theme}>{children}</ThemeProvider>
485
- </EnsureSingleNavigator>
486
- </DeprecatedNavigationInChildContext.Provider>
487
- </UnhandledActionContext.Provider>
488
- </ConsumedParamsContext.Provider>
519
+ <DeprecatedNavigationInChildContext.Provider
520
+ value={navigationInChildEnabled}
521
+ >
522
+ <EnsureSingleNavigator>
523
+ <ThemeProvider value={theme}>{children}</ThemeProvider>
524
+ </EnsureSingleNavigator>
525
+ </DeprecatedNavigationInChildContext.Provider>
526
+ </UnhandledActionContext.Provider>
527
+ </ConsumedParamsContext.Provider>
528
+ </OptionsGetterContext.Provider>
489
529
  </NavigationStateContext.Provider>
490
530
  </NavigationBuilderContext.Provider>
491
531
  </NavigationContainerRefContext.Provider>
@@ -47,15 +47,17 @@ export type FocusedNavigationListener = <T>(
47
47
 
48
48
  export type GetStateListener = () => NavigationState;
49
49
 
50
+ export type WithStackTrace = (
51
+ entry: (...args: never[]) => void,
52
+ callback: () => void
53
+ ) => void;
54
+
50
55
  export type ChildBeforeRemoveListener = (
51
56
  action: NavigationAction,
52
57
  nextState: NavigationState | PartialState<NavigationState> | undefined
53
58
  ) => boolean;
54
59
 
55
- /**
56
- * Context which holds the required helpers needed to build nested navigators.
57
- */
58
- export const NavigationBuilderContext = React.createContext<{
60
+ type NavigationBuilderContextValue = {
59
61
  onAction?: (
60
62
  action: NavigationAction,
61
63
  visitedNavigators?: Set<string>
@@ -71,16 +73,24 @@ export const NavigationBuilderContext = React.createContext<{
71
73
  getIsStateEmitted: () => boolean;
72
74
  scheduleUpdate: (callback: () => void) => void;
73
75
  flushUpdates: () => void;
74
- stackRef?: React.RefObject<string | undefined>;
75
- }>({
76
- onDispatchAction: () => undefined,
77
- onEmitEvent: () => undefined,
78
- onOptionsChange: () => undefined,
79
- getIsStateEmitted: () => false,
80
- scheduleUpdate: () => {
81
- throw new Error("Couldn't find a context for scheduling updates.");
82
- },
83
- flushUpdates: () => {
84
- throw new Error("Couldn't find a context for flushing updates.");
85
- },
86
- });
76
+ withStackTrace: WithStackTrace;
77
+ };
78
+
79
+ /**
80
+ * Context which holds the required helpers needed to build nested navigators.
81
+ */
82
+ export const NavigationBuilderContext = React.createContext<
83
+ NavigationBuilderContextValue | undefined
84
+ >(undefined);
85
+
86
+ export function useNavigationBuilderContext() {
87
+ const value = React.useContext(NavigationBuilderContext);
88
+
89
+ if (value == null) {
90
+ throw new Error(
91
+ "Couldn't find a navigation builder context. Is your component inside NavigationContainer?"
92
+ );
93
+ }
94
+
95
+ return value;
96
+ }
@@ -1,10 +1,20 @@
1
1
  import * as React from 'react';
2
2
 
3
+ import { NavigationBuilderContext } from './NavigationBuilderContext';
4
+ import { NavigationContainerRefContext } from './NavigationContainerRefContext';
3
5
  import { NavigationContext } from './NavigationContext';
4
6
  import { NavigationFocusedRouteStateContext } from './NavigationFocusedRouteStateContext';
7
+ import { NavigationHelpersContext } from './NavigationHelpersContext';
5
8
  import { NavigationIndependentTreeContext } from './NavigationIndependentTreeContext';
6
- import { NavigationRouteContext } from './NavigationProvider';
7
- import { IsFocusedContext } from './useIsFocused';
9
+ // eslint-disable-next-line import-x/no-deprecated
10
+ import { NavigationMetaContext } from './NavigationMetaContext';
11
+ import {
12
+ NamedRouteContextListContext,
13
+ NavigationRouteContext,
14
+ } from './NavigationProvider';
15
+ import { PreventRemoveContext } from './PreventRemoveContext';
16
+ import { FocusedRouteKeyContext, IsFocusedContext } from './useIsFocused';
17
+ import { NavigationStateListenerContext } from './useNavigationState';
8
18
 
9
19
  /**
10
20
  * Component to make the child navigation container independent of parent containers.
@@ -16,16 +26,34 @@ export function NavigationIndependentTree({
16
26
  }) {
17
27
  return (
18
28
  // We need to clear any existing contexts for nested independent container to work correctly
19
- <NavigationRouteContext.Provider value={undefined}>
20
- <NavigationContext.Provider value={undefined}>
21
- <NavigationFocusedRouteStateContext.Provider value={undefined}>
22
- <IsFocusedContext.Provider value={undefined}>
23
- <NavigationIndependentTreeContext.Provider value>
24
- {children}
25
- </NavigationIndependentTreeContext.Provider>
26
- </IsFocusedContext.Provider>
27
- </NavigationFocusedRouteStateContext.Provider>
28
- </NavigationContext.Provider>
29
- </NavigationRouteContext.Provider>
29
+ <NavigationIndependentTreeContext.Provider value>
30
+ <NavigationContainerRefContext.Provider value={undefined}>
31
+ <NavigationBuilderContext.Provider value={undefined}>
32
+ <NavigationMetaContext.Provider value={undefined}>
33
+ <NavigationHelpersContext.Provider value={undefined}>
34
+ <NavigationStateListenerContext.Provider value={undefined}>
35
+ <FocusedRouteKeyContext.Provider value={undefined}>
36
+ <PreventRemoveContext.Provider value={undefined}>
37
+ <NamedRouteContextListContext.Provider value={undefined}>
38
+ <NavigationRouteContext.Provider value={undefined}>
39
+ <NavigationContext.Provider value={undefined}>
40
+ <IsFocusedContext.Provider value={undefined}>
41
+ <NavigationFocusedRouteStateContext.Provider
42
+ value={undefined}
43
+ >
44
+ {children}
45
+ </NavigationFocusedRouteStateContext.Provider>
46
+ </IsFocusedContext.Provider>
47
+ </NavigationContext.Provider>
48
+ </NavigationRouteContext.Provider>
49
+ </NamedRouteContextListContext.Provider>
50
+ </PreventRemoveContext.Provider>
51
+ </FocusedRouteKeyContext.Provider>
52
+ </NavigationStateListenerContext.Provider>
53
+ </NavigationHelpersContext.Provider>
54
+ </NavigationMetaContext.Provider>
55
+ </NavigationBuilderContext.Provider>
56
+ </NavigationContainerRefContext.Provider>
57
+ </NavigationIndependentTreeContext.Provider>
30
58
  );
31
59
  }
@@ -1,13 +1,13 @@
1
1
  import * as React from 'react';
2
2
 
3
3
  /**
4
- * Context with additional metadata to pass to child navigator in a screen.
5
- * For example, child native stack to know it's inside native tabs.
6
- * So it doesn't implement features such as `popToTop` that are handled by native tabs.
4
+ * Context with additional metadata to pass to child navigators in a screen.
7
5
  *
8
6
  * Consumers should not make any assumptions about the shape of the object.
9
7
  * It can be different depending on the navigator and may change without notice.
10
8
  * This is not intended to be used by application code.
9
+ *
10
+ * @deprecated
11
11
  */
12
12
  export const NavigationMetaContext = React.createContext<object | undefined>(
13
13
  undefined
@@ -37,13 +37,16 @@ export function NavigationProvider({ route, navigation, children }: Props) {
37
37
  ? focusedRouteKey === route.key
38
38
  : false;
39
39
 
40
- return (
41
- <NavigationRouteContext.Provider value={route}>
42
- <NavigationContext.Provider value={navigation}>
43
- <IsFocusedContext.Provider value={isFocused}>
44
- {children}
45
- </IsFocusedContext.Provider>
46
- </NavigationContext.Provider>
47
- </NavigationRouteContext.Provider>
40
+ return React.useMemo(
41
+ () => (
42
+ <NavigationRouteContext.Provider value={route}>
43
+ <NavigationContext.Provider value={navigation}>
44
+ <IsFocusedContext.Provider value={isFocused}>
45
+ {children}
46
+ </IsFocusedContext.Provider>
47
+ </NavigationContext.Provider>
48
+ </NavigationRouteContext.Provider>
49
+ ),
50
+ [children, isFocused, navigation, route]
48
51
  );
49
52
  }
@@ -14,10 +14,6 @@ export const NavigationStateContext = React.createContext<{
14
14
  state: NavigationState | PartialState<NavigationState> | undefined
15
15
  ) => void;
16
16
  getIsInitial: () => boolean;
17
- addOptionsGetter?: (
18
- key: string,
19
- getter: () => object | undefined | null
20
- ) => void;
21
17
  }>({
22
18
  isDefault: true,
23
19
 
@@ -1,4 +1,3 @@
1
- import { nanoid } from 'nanoid/non-secure';
2
1
  import * as React from 'react';
3
2
  import useLatestCallback from 'use-latest-callback';
4
3
 
@@ -34,7 +33,8 @@ const transformPreventedRoutes = (
34
33
  * Component used for managing which routes have to be prevented from removal in native-stack.
35
34
  */
36
35
  export function PreventRemoveProvider({ children }: Props) {
37
- const [parentId] = React.useState(() => nanoid());
36
+ const parentId = React.useId();
37
+
38
38
  const [preventedRoutesMap, setPreventedRoutesMap] =
39
39
  React.useState<PreventedRoutesMap>(() => new Map());
40
40
 
@@ -50,15 +50,9 @@ export function PreventRemoveProvider({ children }: Props) {
50
50
 
51
51
  const setPreventRemove = useLatestCallback(
52
52
  (id: string, routeKey: string, preventRemove: boolean): void => {
53
- if (
54
- preventRemove &&
55
- (navigation == null ||
56
- navigation
57
- ?.getState()
58
- .routes.every((route) => route.key !== routeKey))
59
- ) {
53
+ if (preventRemove && navigation == null) {
60
54
  throw new Error(
61
- `Couldn't find a route with the key ${routeKey}. This is likely a bug in the navigator.\n\nIf you're using a custom navigator, make sure that the navigator content is wrapped by the 'render' function returned by 'useNavigationBuilder'.`
55
+ "Couldn't find a navigation object. This is likely a bug in the navigator.\n\nIf you're using a custom navigator, make sure that the navigator content is wrapped by the 'render' function returned by 'useNavigationBuilder'."
62
56
  );
63
57
  }
64
58
 
package/src/SceneView.tsx CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  import { NavigationStateContext } from './NavigationStateContext';
16
16
  import { StaticContainer } from './StaticContainer';
17
17
  import type { NavigationProp, RouteConfigComponent } from './types';
18
- import { useOptionsGetters } from './useOptionsGetters';
18
+ import { OptionsGetterContext, useOptionsGetters } from './useOptionsGetters';
19
19
 
20
20
  type Props<State extends NavigationState, ScreenOptions extends {}> = {
21
21
  screen: RouteConfigComponent<ParamListBase, string> & { name: string };
@@ -163,17 +163,8 @@ export function SceneView<
163
163
  getKey,
164
164
  setKey,
165
165
  getIsInitial,
166
- addOptionsGetter,
167
166
  }),
168
- [
169
- routeState,
170
- getCurrentState,
171
- setCurrentState,
172
- getKey,
173
- setKey,
174
- getIsInitial,
175
- addOptionsGetter,
176
- ]
167
+ [routeState, getCurrentState, setCurrentState, getKey, setKey, getIsInitial]
177
168
  );
178
169
 
179
170
  const ScreenComponent = screen.getComponent
@@ -183,20 +174,22 @@ export function SceneView<
183
174
  return (
184
175
  <NavigationStateContext.Provider value={context}>
185
176
  <NavigationFocusedRouteStateContext.Provider value={focusedRouteState}>
186
- <EnsureSingleNavigator>
187
- <StaticContainer
188
- name={screen.name}
189
- render={ScreenComponent || screen.children}
190
- navigation={navigation}
191
- route={route}
192
- >
193
- {ScreenComponent !== undefined ? (
194
- <ScreenComponent navigation={navigation} route={route} />
195
- ) : screen.children !== undefined ? (
196
- screen.children({ navigation, route })
197
- ) : null}
198
- </StaticContainer>
199
- </EnsureSingleNavigator>
177
+ <OptionsGetterContext.Provider value={addOptionsGetter}>
178
+ <EnsureSingleNavigator>
179
+ <StaticContainer
180
+ name={screen.name}
181
+ render={ScreenComponent || screen.children}
182
+ navigation={navigation}
183
+ route={route}
184
+ >
185
+ {ScreenComponent !== undefined ? (
186
+ <ScreenComponent navigation={navigation} route={route} />
187
+ ) : screen.children !== undefined ? (
188
+ screen.children({ navigation, route })
189
+ ) : null}
190
+ </StaticContainer>
191
+ </EnsureSingleNavigator>
192
+ </OptionsGetterContext.Provider>
200
193
  </NavigationFocusedRouteStateContext.Provider>
201
194
  </NavigationStateContext.Provider>
202
195
  );