@react-navigation/core 8.0.0-alpha.4 → 8.0.0-alpha.40

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 (323) hide show
  1. package/README.md +17 -14
  2. package/lib/module/BaseNavigationContainer.js +168 -87
  3. package/lib/module/BaseNavigationContainer.js.map +1 -1
  4. package/lib/module/ConsumedParamsContext.js +5 -0
  5. package/lib/module/ConsumedParamsContext.js.map +1 -0
  6. package/lib/module/DataLoading.js +129 -0
  7. package/lib/module/DataLoading.js.map +1 -0
  8. package/lib/module/NavigationBuilderContext.js +7 -10
  9. package/lib/module/NavigationBuilderContext.js.map +1 -1
  10. package/lib/module/NavigationIndependentTree.js +54 -9
  11. package/lib/module/NavigationIndependentTree.js.map +1 -1
  12. package/lib/module/NavigationProvider.js +36 -11
  13. package/lib/module/NavigationProvider.js.map +1 -1
  14. package/lib/module/NavigationRootContext.js +8 -0
  15. package/lib/module/NavigationRootContext.js.map +1 -0
  16. package/lib/module/NavigationStateContext.js +3 -0
  17. package/lib/module/NavigationStateContext.js.map +1 -1
  18. package/lib/module/PreventRemoveContext.js.map +1 -1
  19. package/lib/module/PreventRemoveProvider.js +40 -31
  20. package/lib/module/PreventRemoveProvider.js.map +1 -1
  21. package/lib/module/SceneView.js +12 -42
  22. package/lib/module/SceneView.js.map +1 -1
  23. package/lib/module/StaticNavigation.js +219 -67
  24. package/lib/module/StaticNavigation.js.map +1 -1
  25. package/lib/module/StaticTreeContext.js +5 -0
  26. package/lib/module/StaticTreeContext.js.map +1 -0
  27. package/lib/module/createNavigationContainerRef.js +7 -9
  28. package/lib/module/createNavigationContainerRef.js.map +1 -1
  29. package/lib/module/createNavigatorFactory.js +27 -5
  30. package/lib/module/createNavigatorFactory.js.map +1 -1
  31. package/lib/module/findFocusedRoute.js +7 -4
  32. package/lib/module/findFocusedRoute.js.map +1 -1
  33. package/lib/module/getActionFromState.js +45 -20
  34. package/lib/module/getActionFromState.js.map +1 -1
  35. package/lib/module/getPathFromState.js +204 -94
  36. package/lib/module/getPathFromState.js.map +1 -1
  37. package/lib/module/getPatternParts.js +61 -14
  38. package/lib/module/getPatternParts.js.map +1 -1
  39. package/lib/module/getStateFromPath.js +608 -272
  40. package/lib/module/getStateFromPath.js.map +1 -1
  41. package/lib/module/getStateFromRouteParams.js +23 -0
  42. package/lib/module/getStateFromRouteParams.js.map +1 -0
  43. package/lib/module/index.js +7 -6
  44. package/lib/module/index.js.map +1 -1
  45. package/lib/module/internal.js +2 -0
  46. package/lib/module/internal.js.map +1 -0
  47. package/lib/module/isRecordEqual.js +1 -1
  48. package/lib/module/isRecordEqual.js.map +1 -1
  49. package/lib/module/queryString.js +71 -0
  50. package/lib/module/queryString.js.map +1 -0
  51. package/lib/module/theming/useTheme.js +1 -1
  52. package/lib/module/theming/useTheme.js.map +1 -1
  53. package/lib/module/types.js +35 -1
  54. package/lib/module/types.js.map +1 -1
  55. package/lib/module/useDescriptors.js +65 -25
  56. package/lib/module/useDescriptors.js.map +1 -1
  57. package/lib/module/useEventEmitter.js +48 -33
  58. package/lib/module/useEventEmitter.js.map +1 -1
  59. package/lib/module/useFocusEffect.js +4 -2
  60. package/lib/module/useFocusEffect.js.map +1 -1
  61. package/lib/module/useFocusEvents.js +15 -5
  62. package/lib/module/useFocusEvents.js.map +1 -1
  63. package/lib/module/useFocusedListenersChildrenAdapter.js +3 -3
  64. package/lib/module/useFocusedListenersChildrenAdapter.js.map +1 -1
  65. package/lib/module/useIsFocused.js +8 -12
  66. package/lib/module/useIsFocused.js.map +1 -1
  67. package/lib/module/useKeyedChildListeners.js +5 -2
  68. package/lib/module/useKeyedChildListeners.js.map +1 -1
  69. package/lib/module/useLazyValue.js.map +1 -1
  70. package/lib/module/useNavigation.js +4 -17
  71. package/lib/module/useNavigation.js.map +1 -1
  72. package/lib/module/useNavigationBuilder.js +244 -147
  73. package/lib/module/useNavigationBuilder.js.map +1 -1
  74. package/lib/module/useNavigationCache.js +92 -89
  75. package/lib/module/useNavigationCache.js.map +1 -1
  76. package/lib/module/useNavigationHelpers.js +22 -29
  77. package/lib/module/useNavigationHelpers.js.map +1 -1
  78. package/lib/module/useNavigationIndependentTree.js +1 -1
  79. package/lib/module/useNavigationIndependentTree.js.map +1 -1
  80. package/lib/module/useNavigationState.js +158 -46
  81. package/lib/module/useNavigationState.js.map +1 -1
  82. package/lib/module/useOnAction.js +58 -11
  83. package/lib/module/useOnAction.js.map +1 -1
  84. package/lib/module/useOnGetNavigation.js +26 -0
  85. package/lib/module/useOnGetNavigation.js.map +1 -0
  86. package/lib/module/useOnGetState.js +7 -4
  87. package/lib/module/useOnGetState.js.map +1 -1
  88. package/lib/module/useOnPreventRemove.js +40 -31
  89. package/lib/module/useOnPreventRemove.js.map +1 -1
  90. package/lib/module/useOnRouteFocus.js +2 -2
  91. package/lib/module/useOnRouteFocus.js.map +1 -1
  92. package/lib/module/useOptionsGetters.js +34 -24
  93. package/lib/module/useOptionsGetters.js.map +1 -1
  94. package/lib/module/usePreventRemove.js +11 -5
  95. package/lib/module/usePreventRemove.js.map +1 -1
  96. package/lib/module/usePreventRemoveContext.js +2 -2
  97. package/lib/module/usePreventRemoveContext.js.map +1 -1
  98. package/lib/module/useRegisterNavigator.js +3 -4
  99. package/lib/module/useRegisterNavigator.js.map +1 -1
  100. package/lib/module/useRoute.js +2 -0
  101. package/lib/module/useRoute.js.map +1 -1
  102. package/lib/module/useRouteCache.js +51 -35
  103. package/lib/module/useRouteCache.js.map +1 -1
  104. package/lib/module/useScheduleUpdate.js +12 -10
  105. package/lib/module/useScheduleUpdate.js.map +1 -1
  106. package/lib/module/useStateForPath.js +1 -1
  107. package/lib/module/useStateForPath.js.map +1 -1
  108. package/lib/module/useSyncState.js +37 -15
  109. package/lib/module/useSyncState.js.map +1 -1
  110. package/lib/module/validatePathConfig.js +50 -36
  111. package/lib/module/validatePathConfig.js.map +1 -1
  112. package/lib/typescript/src/BaseNavigationContainer.d.ts +6 -3
  113. package/lib/typescript/src/BaseNavigationContainer.d.ts.map +1 -1
  114. package/lib/typescript/src/ConsumedParamsContext.d.ts +3 -0
  115. package/lib/typescript/src/ConsumedParamsContext.d.ts.map +1 -0
  116. package/lib/typescript/src/DataLoading.d.ts +21 -0
  117. package/lib/typescript/src/DataLoading.d.ts.map +1 -0
  118. package/lib/typescript/src/EnsureSingleNavigator.d.ts +1 -1
  119. package/lib/typescript/src/EnsureSingleNavigator.d.ts.map +1 -1
  120. package/lib/typescript/src/Group.d.ts +1 -1
  121. package/lib/typescript/src/Group.d.ts.map +1 -1
  122. package/lib/typescript/src/NavigationBuilderContext.d.ts +22 -14
  123. package/lib/typescript/src/NavigationBuilderContext.d.ts.map +1 -1
  124. package/lib/typescript/src/NavigationContainerRefContext.d.ts +1 -1
  125. package/lib/typescript/src/NavigationContainerRefContext.d.ts.map +1 -1
  126. package/lib/typescript/src/NavigationFocusedRouteStateContext.d.ts +4 -4
  127. package/lib/typescript/src/NavigationFocusedRouteStateContext.d.ts.map +1 -1
  128. package/lib/typescript/src/NavigationHelpersContext.d.ts +1 -1
  129. package/lib/typescript/src/NavigationHelpersContext.d.ts.map +1 -1
  130. package/lib/typescript/src/NavigationIndependentTree.d.ts +1 -1
  131. package/lib/typescript/src/NavigationIndependentTree.d.ts.map +1 -1
  132. package/lib/typescript/src/NavigationProvider.d.ts +21 -18
  133. package/lib/typescript/src/NavigationProvider.d.ts.map +1 -1
  134. package/lib/typescript/src/NavigationRootContext.d.ts +8 -0
  135. package/lib/typescript/src/NavigationRootContext.d.ts.map +1 -0
  136. package/lib/typescript/src/NavigationStateContext.d.ts +4 -3
  137. package/lib/typescript/src/NavigationStateContext.d.ts.map +1 -1
  138. package/lib/typescript/src/PreventRemoveContext.d.ts +1 -0
  139. package/lib/typescript/src/PreventRemoveContext.d.ts.map +1 -1
  140. package/lib/typescript/src/PreventRemoveProvider.d.ts +1 -1
  141. package/lib/typescript/src/PreventRemoveProvider.d.ts.map +1 -1
  142. package/lib/typescript/src/SceneView.d.ts +5 -2
  143. package/lib/typescript/src/SceneView.d.ts.map +1 -1
  144. package/lib/typescript/src/Screen.d.ts +1 -1
  145. package/lib/typescript/src/Screen.d.ts.map +1 -1
  146. package/lib/typescript/src/StaticContainer.d.ts +1 -1
  147. package/lib/typescript/src/StaticContainer.d.ts.map +1 -1
  148. package/lib/typescript/src/StaticNavigation.d.ts +189 -111
  149. package/lib/typescript/src/StaticNavigation.d.ts.map +1 -1
  150. package/lib/typescript/src/StaticTreeContext.d.ts +4 -0
  151. package/lib/typescript/src/StaticTreeContext.d.ts.map +1 -0
  152. package/lib/typescript/src/createNavigationContainerRef.d.ts +1 -1
  153. package/lib/typescript/src/createNavigationContainerRef.d.ts.map +1 -1
  154. package/lib/typescript/src/createNavigatorFactory.d.ts +23 -5
  155. package/lib/typescript/src/createNavigatorFactory.d.ts.map +1 -1
  156. package/lib/typescript/src/findFocusedRoute.d.ts +3 -8
  157. package/lib/typescript/src/findFocusedRoute.d.ts.map +1 -1
  158. package/lib/typescript/src/getActionFromState.d.ts +4 -4
  159. package/lib/typescript/src/getActionFromState.d.ts.map +1 -1
  160. package/lib/typescript/src/getPathFromState.d.ts +3 -3
  161. package/lib/typescript/src/getPathFromState.d.ts.map +1 -1
  162. package/lib/typescript/src/getPatternParts.d.ts +5 -2
  163. package/lib/typescript/src/getPatternParts.d.ts.map +1 -1
  164. package/lib/typescript/src/getStateFromPath.d.ts +4 -7
  165. package/lib/typescript/src/getStateFromPath.d.ts.map +1 -1
  166. package/lib/typescript/src/getStateFromRouteParams.d.ts +3 -0
  167. package/lib/typescript/src/getStateFromRouteParams.d.ts.map +1 -0
  168. package/lib/typescript/src/index.d.ts +36 -33
  169. package/lib/typescript/src/index.d.ts.map +1 -1
  170. package/lib/typescript/src/internal.d.ts +3 -0
  171. package/lib/typescript/src/internal.d.ts.map +1 -0
  172. package/lib/typescript/src/isRecordEqual.d.ts.map +1 -1
  173. package/lib/typescript/src/queryString.d.ts +5 -0
  174. package/lib/typescript/src/queryString.d.ts.map +1 -0
  175. package/lib/typescript/src/theming/ThemeContext.d.ts +1 -1
  176. package/lib/typescript/src/theming/ThemeContext.d.ts.map +1 -1
  177. package/lib/typescript/src/theming/ThemeProvider.d.ts +2 -2
  178. package/lib/typescript/src/theming/ThemeProvider.d.ts.map +1 -1
  179. package/lib/typescript/src/theming/useTheme.d.ts +1 -1
  180. package/lib/typescript/src/theming/useTheme.d.ts.map +1 -1
  181. package/lib/typescript/src/types.d.ts +265 -167
  182. package/lib/typescript/src/types.d.ts.map +1 -1
  183. package/lib/typescript/src/useChildListeners.d.ts +3 -3
  184. package/lib/typescript/src/useChildListeners.d.ts.map +1 -1
  185. package/lib/typescript/src/useDescriptors.d.ts +13 -11
  186. package/lib/typescript/src/useDescriptors.d.ts.map +1 -1
  187. package/lib/typescript/src/useEventEmitter.d.ts +2 -2
  188. package/lib/typescript/src/useEventEmitter.d.ts.map +1 -1
  189. package/lib/typescript/src/useFocusEffect.d.ts.map +1 -1
  190. package/lib/typescript/src/useFocusEvents.d.ts +2 -2
  191. package/lib/typescript/src/useFocusEvents.d.ts.map +1 -1
  192. package/lib/typescript/src/useFocusedListenersChildrenAdapter.d.ts +2 -2
  193. package/lib/typescript/src/useFocusedListenersChildrenAdapter.d.ts.map +1 -1
  194. package/lib/typescript/src/useIsFocused.d.ts +4 -0
  195. package/lib/typescript/src/useIsFocused.d.ts.map +1 -1
  196. package/lib/typescript/src/useKeyedChildListeners.d.ts +4 -3
  197. package/lib/typescript/src/useKeyedChildListeners.d.ts.map +1 -1
  198. package/lib/typescript/src/useLazyValue.d.ts.map +1 -1
  199. package/lib/typescript/src/useNavigation.d.ts +4 -2
  200. package/lib/typescript/src/useNavigation.d.ts.map +1 -1
  201. package/lib/typescript/src/useNavigationBuilder.d.ts +22 -63
  202. package/lib/typescript/src/useNavigationBuilder.d.ts.map +1 -1
  203. package/lib/typescript/src/useNavigationCache.d.ts +6 -5
  204. package/lib/typescript/src/useNavigationCache.d.ts.map +1 -1
  205. package/lib/typescript/src/useNavigationContainerRef.d.ts +1 -1
  206. package/lib/typescript/src/useNavigationContainerRef.d.ts.map +1 -1
  207. package/lib/typescript/src/useNavigationHelpers.d.ts +18 -58
  208. package/lib/typescript/src/useNavigationHelpers.d.ts.map +1 -1
  209. package/lib/typescript/src/useNavigationState.d.ts +19 -3
  210. package/lib/typescript/src/useNavigationState.d.ts.map +1 -1
  211. package/lib/typescript/src/useOnAction.d.ts +9 -9
  212. package/lib/typescript/src/useOnAction.d.ts.map +1 -1
  213. package/lib/typescript/src/useOnGetNavigation.d.ts +12 -0
  214. package/lib/typescript/src/useOnGetNavigation.d.ts.map +1 -0
  215. package/lib/typescript/src/useOnGetState.d.ts +1 -1
  216. package/lib/typescript/src/useOnGetState.d.ts.map +1 -1
  217. package/lib/typescript/src/useOnPreventRemove.d.ts +5 -9
  218. package/lib/typescript/src/useOnPreventRemove.d.ts.map +1 -1
  219. package/lib/typescript/src/useOnRouteFocus.d.ts +6 -6
  220. package/lib/typescript/src/useOnRouteFocus.d.ts.map +1 -1
  221. package/lib/typescript/src/useOptionsGetters.d.ts +2 -4
  222. package/lib/typescript/src/useOptionsGetters.d.ts.map +1 -1
  223. package/lib/typescript/src/usePreventRemove.d.ts.map +1 -1
  224. package/lib/typescript/src/usePreventRemoveContext.d.ts +2 -1
  225. package/lib/typescript/src/usePreventRemoveContext.d.ts.map +1 -1
  226. package/lib/typescript/src/useRegisterNavigator.d.ts.map +1 -1
  227. package/lib/typescript/src/useRoute.d.ts +7 -3
  228. package/lib/typescript/src/useRoute.d.ts.map +1 -1
  229. package/lib/typescript/src/useRouteCache.d.ts +7 -12
  230. package/lib/typescript/src/useRouteCache.d.ts.map +1 -1
  231. package/lib/typescript/src/useScheduleUpdate.d.ts +5 -4
  232. package/lib/typescript/src/useScheduleUpdate.d.ts.map +1 -1
  233. package/lib/typescript/src/useStateForPath.d.ts +1 -1
  234. package/lib/typescript/src/useStateForPath.d.ts.map +1 -1
  235. package/lib/typescript/src/useSyncState.d.ts +1 -0
  236. package/lib/typescript/src/useSyncState.d.ts.map +1 -1
  237. package/lib/typescript/src/utilities.d.ts +79 -39
  238. package/lib/typescript/src/utilities.d.ts.map +1 -1
  239. package/lib/typescript/src/validatePathConfig.d.ts.map +1 -1
  240. package/package.json +26 -22
  241. package/src/BaseNavigationContainer.tsx +468 -333
  242. package/src/ConsumedParamsContext.tsx +5 -0
  243. package/src/DataLoading.tsx +206 -0
  244. package/src/NavigationBuilderContext.tsx +44 -25
  245. package/src/NavigationFocusedRouteStateContext.tsx +4 -4
  246. package/src/NavigationIndependentTree.tsx +60 -12
  247. package/src/NavigationProvider.tsx +47 -20
  248. package/src/NavigationRootContext.tsx +11 -0
  249. package/src/NavigationStateContext.tsx +9 -6
  250. package/src/PreventRemoveContext.tsx +1 -0
  251. package/src/PreventRemoveProvider.tsx +55 -56
  252. package/src/SceneView.tsx +14 -40
  253. package/src/StaticNavigation.tsx +715 -328
  254. package/src/StaticTreeContext.tsx +7 -0
  255. package/src/createNavigationContainerRef.tsx +12 -11
  256. package/src/createNavigatorFactory.tsx +92 -8
  257. package/src/findFocusedRoute.tsx +16 -16
  258. package/src/getActionFromState.tsx +87 -51
  259. package/src/getPathFromState.tsx +310 -134
  260. package/src/getPatternParts.tsx +98 -16
  261. package/src/getStateFromPath.tsx +971 -344
  262. package/src/getStateFromRouteParams.tsx +59 -0
  263. package/src/index.tsx +57 -6
  264. package/src/internal.tsx +2 -0
  265. package/src/isRecordEqual.tsx +3 -1
  266. package/src/queryString.ts +109 -0
  267. package/src/theming/useTheme.tsx +1 -1
  268. package/src/types.tsx +799 -377
  269. package/src/useDescriptors.tsx +151 -43
  270. package/src/useEventEmitter.tsx +53 -39
  271. package/src/useFocusEffect.tsx +5 -2
  272. package/src/useFocusEvents.tsx +19 -8
  273. package/src/useFocusedListenersChildrenAdapter.tsx +3 -3
  274. package/src/useIsFocused.tsx +18 -21
  275. package/src/useKeyedChildListeners.tsx +5 -2
  276. package/src/useLazyValue.tsx +2 -2
  277. package/src/useNavigation.tsx +9 -26
  278. package/src/useNavigationBuilder.tsx +370 -201
  279. package/src/useNavigationCache.tsx +148 -123
  280. package/src/useNavigationHelpers.tsx +27 -37
  281. package/src/useNavigationIndependentTree.tsx +1 -1
  282. package/src/useNavigationState.tsx +207 -69
  283. package/src/useOnAction.tsx +92 -18
  284. package/src/useOnGetNavigation.tsx +30 -0
  285. package/src/useOnGetState.tsx +8 -4
  286. package/src/useOnPreventRemove.tsx +78 -43
  287. package/src/useOnRouteFocus.tsx +11 -15
  288. package/src/useOptionsGetters.tsx +41 -28
  289. package/src/usePreventRemove.tsx +13 -5
  290. package/src/usePreventRemoveContext.tsx +2 -2
  291. package/src/useRegisterNavigator.tsx +4 -4
  292. package/src/useRoute.tsx +20 -6
  293. package/src/useRouteCache.tsx +57 -35
  294. package/src/useScheduleUpdate.tsx +13 -11
  295. package/src/useStateForPath.tsx +1 -1
  296. package/src/useSyncState.tsx +39 -15
  297. package/src/utilities.tsx +151 -35
  298. package/src/validatePathConfig.tsx +86 -57
  299. package/lib/module/CurrentRenderContext.js +0 -10
  300. package/lib/module/CurrentRenderContext.js.map +0 -1
  301. package/lib/module/NavigationMetaContext.js +0 -15
  302. package/lib/module/NavigationMetaContext.js.map +0 -1
  303. package/lib/module/checkSerializable.js +0 -46
  304. package/lib/module/checkSerializable.js.map +0 -1
  305. package/lib/module/useComponent.js +0 -34
  306. package/lib/module/useComponent.js.map +0 -1
  307. package/lib/module/useCurrentRender.js +0 -19
  308. package/lib/module/useCurrentRender.js.map +0 -1
  309. package/lib/typescript/src/CurrentRenderContext.d.ts +0 -9
  310. package/lib/typescript/src/CurrentRenderContext.d.ts.map +0 -1
  311. package/lib/typescript/src/NavigationMetaContext.d.ts +0 -12
  312. package/lib/typescript/src/NavigationMetaContext.d.ts.map +0 -1
  313. package/lib/typescript/src/checkSerializable.d.ts +0 -10
  314. package/lib/typescript/src/checkSerializable.d.ts.map +0 -1
  315. package/lib/typescript/src/useComponent.d.ts +0 -7
  316. package/lib/typescript/src/useComponent.d.ts.map +0 -1
  317. package/lib/typescript/src/useCurrentRender.d.ts +0 -14
  318. package/lib/typescript/src/useCurrentRender.d.ts.map +0 -1
  319. package/src/CurrentRenderContext.tsx +0 -9
  320. package/src/NavigationMetaContext.tsx +0 -14
  321. package/src/checkSerializable.tsx +0 -74
  322. package/src/useComponent.tsx +0 -37
  323. package/src/useCurrentRender.tsx +0 -31
@@ -9,34 +9,44 @@ import {
9
9
  } from '@react-navigation/routers';
10
10
  import * as React from 'react';
11
11
  import useLatestCallback from 'use-latest-callback';
12
+ import warnOnce from 'warn-once';
12
13
 
13
14
  import { checkDuplicateRouteNames } from './checkDuplicateRouteNames';
14
- import { checkSerializable } from './checkSerializable';
15
+ import { ConsumedParamsContext } from './ConsumedParamsContext';
15
16
  import { NOT_INITIALIZED_ERROR } from './createNavigationContainerRef';
16
17
  import { EnsureSingleNavigator } from './EnsureSingleNavigator';
17
18
  import { findFocusedRoute } from './findFocusedRoute';
18
- import { NavigationBuilderContext } from './NavigationBuilderContext';
19
+ import {
20
+ NavigationBuilderContext,
21
+ type WithStackTrace,
22
+ } from './NavigationBuilderContext';
19
23
  import { NavigationContainerRefContext } from './NavigationContainerRefContext';
20
24
  import { NavigationIndependentTreeContext } from './NavigationIndependentTreeContext';
25
+ import { NavigationRootContext } from './NavigationRootContext';
21
26
  import { NavigationStateContext } from './NavigationStateContext';
22
27
  import { ThemeProvider } from './theming/ThemeProvider';
23
28
  import type {
29
+ EventListenerCallback,
30
+ GenericNavigation,
24
31
  NavigationContainerEventMap,
25
32
  NavigationContainerProps,
26
33
  NavigationContainerRef,
34
+ RootParamList,
27
35
  } from './types';
28
36
  import { UnhandledActionContext } from './UnhandledActionContext';
29
37
  import { useChildListeners } from './useChildListeners';
30
38
  import { useEventEmitter } from './useEventEmitter';
31
39
  import { useKeyedChildListeners } from './useKeyedChildListeners';
40
+ import { useLazyValue } from './useLazyValue';
32
41
  import { useNavigationIndependentTree } from './useNavigationIndependentTree';
33
42
  import { useOptionsGetters } from './useOptionsGetters';
34
43
  import { useSyncState } from './useSyncState';
35
44
 
36
45
  type State = NavigationState | PartialState<NavigationState> | undefined;
37
46
 
38
- const serializableWarnings: string[] = [];
39
- const duplicateNameWarnings: string[] = [];
47
+ type Props<ParamList extends {}> = NavigationContainerProps & {
48
+ ref?: React.Ref<NavigationContainerRef<ParamList>> | undefined;
49
+ };
40
50
 
41
51
  /**
42
52
  * Remove `key` and `routeNames` from the state objects recursively to get partial state.
@@ -80,398 +90,523 @@ const getPartialState = (
80
90
  * @param props.children Child elements to render the content.
81
91
  * @param props.ref Ref object which refers to the navigation object containing helper methods.
82
92
  */
83
- export const BaseNavigationContainer = React.forwardRef(
84
- function BaseNavigationContainer(
85
- {
86
- initialState,
87
- onStateChange,
88
- onReady,
89
- onUnhandledAction,
90
- theme,
91
- children,
92
- }: NavigationContainerProps,
93
- ref?: React.Ref<NavigationContainerRef<ParamListBase>>
94
- ) {
95
- const parent = React.useContext(NavigationStateContext);
96
- const independent = useNavigationIndependentTree();
97
-
98
- if (!parent.isDefault && !independent) {
99
- throw new Error(
100
- "Looks like you have nested a 'NavigationContainer' inside another. Normally you need only one container at the root of the app, so this was probably an error. If this was intentional, wrap the container in 'NavigationIndependentTree' explicitly. Note that this will make the child navigators disconnected from the parent and you won't be able to navigate between them."
101
- );
102
- }
93
+ export function BaseNavigationContainer<ParamList extends {} = RootParamList>({
94
+ initialState,
95
+ onStateChange,
96
+ onReady,
97
+ onUnhandledAction,
98
+ theme,
99
+ children,
100
+ ref,
101
+ }: Props<ParamList>) {
102
+ const parent = React.use(NavigationStateContext);
103
+ const independent = useNavigationIndependentTree();
104
+
105
+ if (!parent.isDefault && !independent) {
106
+ throw new Error(
107
+ "Looks like you have nested a 'NavigationContainer' inside another. Normally you need only one container at the root of the app, so this was probably an error. If this was intentional, wrap the container in 'NavigationIndependentTree' explicitly. Note that this will make the child navigators disconnected from the parent and you won't be able to navigate between them."
108
+ );
109
+ }
110
+
111
+ const { state, getState, setState, subscribe, scheduleUpdate, flushUpdates } =
112
+ useSyncState<State>(() =>
113
+ getPartialState(initialState == null ? undefined : initialState)
114
+ );
103
115
 
104
- const { state, getState, setState, scheduleUpdate, flushUpdates } =
105
- useSyncState<State>(() =>
106
- getPartialState(initialState == null ? undefined : initialState)
107
- );
116
+ const consumedParams = useLazyValue(() => new WeakMap<object, true>());
108
117
 
109
- const isFirstMountRef = React.useRef<boolean>(true);
118
+ const isFirstMountRef = React.useRef<boolean>(true);
110
119
 
111
- const navigatorKeyRef = React.useRef<string | undefined>(undefined);
120
+ const navigatorKeyRef = React.useRef<string | undefined>(undefined);
112
121
 
113
- const getKey = React.useCallback(() => navigatorKeyRef.current, []);
122
+ const getKey = React.useCallback(() => navigatorKeyRef.current, []);
114
123
 
115
- const setKey = React.useCallback((key: string) => {
116
- navigatorKeyRef.current = key;
117
- }, []);
124
+ const setKey = React.useCallback((key: string) => {
125
+ navigatorKeyRef.current = key;
126
+ }, []);
118
127
 
119
- const { listeners, addListener } = useChildListeners();
128
+ const { listeners, addListener } = useChildListeners();
120
129
 
121
- const { keyedListeners, addKeyedListener } = useKeyedChildListeners();
130
+ const { keyedListeners, addKeyedListener } = useKeyedChildListeners();
122
131
 
123
- const dispatch = useLatestCallback(
124
- (
125
- action:
126
- | NavigationAction
127
- | ((state: NavigationState) => NavigationAction)
128
- ) => {
129
- if (listeners.focus[0] == null) {
130
- console.error(NOT_INITIALIZED_ERROR);
131
- } else {
132
- listeners.focus[0]((navigation) => navigation.dispatch(action));
133
- }
134
- }
135
- );
132
+ const stackRef = React.useRef<string | undefined>(undefined);
136
133
 
137
- const canGoBack = useLatestCallback(() => {
138
- if (listeners.focus[0] == null) {
139
- return false;
134
+ const withStackTrace = React.useCallback<WithStackTrace>(
135
+ (entry, callback) => {
136
+ if (process.env.NODE_ENV === 'production' || stackRef.current != null) {
137
+ callback();
138
+ return;
140
139
  }
141
140
 
142
- const { result, handled } = listeners.focus[0]((navigation) =>
143
- navigation.canGoBack()
144
- );
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);
145
146
 
146
- if (handled) {
147
- return result;
147
+ stackRef.current = error.stack;
148
148
  } else {
149
- return false;
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');
150
156
  }
151
- });
152
157
 
153
- const resetRoot = useLatestCallback(
154
- (state?: PartialState<NavigationState> | NavigationState) => {
155
- const target = state?.key ?? keyedListeners.getState.root?.().key;
156
-
157
- if (target == null) {
158
- console.error(NOT_INITIALIZED_ERROR);
159
- } else {
160
- listeners.focus[0]((navigation) =>
161
- navigation.dispatch({
162
- ...CommonActions.reset(state),
163
- target,
158
+ try {
159
+ callback();
160
+ } finally {
161
+ stackRef.current = undefined;
162
+ }
163
+ },
164
+ []
165
+ );
166
+
167
+ const dispatch = useLatestCallback(
168
+ (
169
+ action: NavigationAction | ((state: NavigationState) => NavigationAction)
170
+ ) => {
171
+ const listener = listeners.focus[0];
172
+
173
+ if (listener == null) {
174
+ console.error(NOT_INITIALIZED_ERROR);
175
+ } else {
176
+ withStackTrace(dispatch, () => {
177
+ listener((navigation) =>
178
+ React.startTransition(() => {
179
+ navigation.dispatch(action);
164
180
  })
165
181
  );
166
- }
182
+ });
167
183
  }
184
+ }
185
+ );
186
+
187
+ const canGoBack = useLatestCallback(() => {
188
+ if (listeners.focus[0] == null) {
189
+ return false;
190
+ }
191
+
192
+ const { result, handled } = listeners.focus[0]((navigation) =>
193
+ navigation.canGoBack()
168
194
  );
169
195
 
170
- const getRootState = useLatestCallback(() => {
171
- return keyedListeners.getState.root?.();
172
- });
196
+ if (handled) {
197
+ return result;
198
+ } else {
199
+ return false;
200
+ }
201
+ });
173
202
 
174
- const getCurrentRoute = useLatestCallback(() => {
175
- const state = getRootState();
203
+ const resetRoot = useLatestCallback(
204
+ (state: PartialState<NavigationState> | NavigationState) => {
205
+ const target = keyedListeners.getState.root?.().key;
206
+ const listener = listeners.focus[0];
176
207
 
177
- if (state == null) {
178
- return undefined;
208
+ if (target == null || listener == null) {
209
+ console.error(NOT_INITIALIZED_ERROR);
210
+ } else {
211
+ listener((navigation) =>
212
+ navigation.dispatch({
213
+ ...CommonActions.reset(state),
214
+ target,
215
+ })
216
+ );
179
217
  }
218
+ }
219
+ );
180
220
 
181
- const route = findFocusedRoute(state);
221
+ const getRootState = useLatestCallback(() => {
222
+ return keyedListeners.getState.root?.();
223
+ });
182
224
 
183
- return route as Route<string> | undefined;
184
- });
225
+ const getCurrentRoute = useLatestCallback(() => {
226
+ const state = getRootState();
227
+
228
+ if (state == null) {
229
+ return undefined;
230
+ }
185
231
 
186
- const isReady = useLatestCallback(() => listeners.focus[0] != null);
232
+ const route = findFocusedRoute(state);
187
233
 
188
- const emitter = useEventEmitter<NavigationContainerEventMap>();
234
+ return route as Route<string> | undefined;
235
+ });
189
236
 
190
- const { addOptionsGetter, getCurrentOptions } = useOptionsGetters({});
237
+ const isReady = useLatestCallback(() => listeners.focus[0] != null);
191
238
 
192
- const navigation: NavigationContainerRef<ParamListBase> = React.useMemo(
193
- () => ({
194
- ...Object.keys(CommonActions).reduce<any>((acc, name) => {
195
- acc[name] = (...args: any[]) =>
196
- // @ts-expect-error: this is ok
197
- dispatch(CommonActions[name](...args));
198
- return acc;
199
- }, {}),
200
- ...emitter.create('root'),
201
- dispatch,
202
- resetRoot,
203
- isFocused: () => true,
204
- canGoBack,
205
- getParent: () => undefined,
206
- getState,
207
- getRootState,
208
- getCurrentRoute,
209
- getCurrentOptions,
210
- isReady,
211
- setOptions: () => {
212
- throw new Error('Cannot call setOptions outside a screen');
213
- },
214
- }),
215
- [
216
- canGoBack,
217
- dispatch,
218
- emitter,
219
- getCurrentOptions,
220
- getCurrentRoute,
221
- getRootState,
222
- getState,
223
- isReady,
224
- resetRoot,
225
- ]
226
- );
239
+ const emitter = useEventEmitter<NavigationContainerEventMap>();
227
240
 
228
- React.useImperativeHandle(ref, () => navigation, [navigation]);
241
+ const { addOptionsGetter, getCurrentOptions } = useOptionsGetters({});
229
242
 
230
- const onDispatchAction = useLatestCallback(
231
- (action: NavigationAction, noop: boolean) => {
232
- emitter.emit({
233
- type: '__unsafe_action__',
234
- data: { action, noop, stack: stackRef.current },
235
- });
243
+ const container: NavigationContainerRef<ParamList> = React.useMemo(
244
+ () => ({
245
+ ...Object.keys(CommonActions).reduce<any>((acc, name) => {
246
+ const helper = (...args: any[]) =>
247
+ withStackTrace(helper, () =>
248
+ // @ts-expect-error: this is ok
249
+ dispatch(CommonActions[name](...args))
250
+ );
251
+
252
+ acc[name] = helper;
253
+
254
+ return acc;
255
+ }, {}),
256
+ ...emitter.create('root'),
257
+ dispatch,
258
+ resetRoot,
259
+ canGoBack,
260
+ getState,
261
+ getRootState,
262
+ getCurrentRoute,
263
+ getCurrentOptions,
264
+ isReady,
265
+ }),
266
+ [
267
+ canGoBack,
268
+ dispatch,
269
+ emitter,
270
+ getCurrentOptions,
271
+ getCurrentRoute,
272
+ getRootState,
273
+ getState,
274
+ isReady,
275
+ resetRoot,
276
+ withStackTrace,
277
+ ]
278
+ );
279
+
280
+ const navigation: GenericNavigation<ParamListBase> = React.useMemo(() => {
281
+ const events = emitter.create('root');
282
+
283
+ const dispatch = (
284
+ thunk: NavigationAction | ((state: NavigationState) => NavigationAction)
285
+ ) => {
286
+ const root = keyedListeners.getNavigation.root?.();
287
+
288
+ if (root == null) {
289
+ console.error(NOT_INITIALIZED_ERROR);
290
+ return;
236
291
  }
237
- );
238
292
 
239
- const onEmitEvent = useLatestCallback(
240
- (event: {
241
- type: string;
242
- defaultPrevented: boolean | undefined;
243
- target: string | undefined;
244
- data: unknown;
245
- }) => {
246
- emitter.emit({
247
- type: '__unsafe_event__',
248
- data: event,
293
+ withStackTrace(dispatch, () => {
294
+ React.startTransition(() => {
295
+ root.dispatch(thunk);
249
296
  });
250
- }
251
- );
297
+ });
298
+ };
299
+
300
+ const helpers = Object.keys(CommonActions).reduce<any>((acc, name) => {
301
+ const helper = (...args: any) => {
302
+ if (
303
+ name === 'setParams' ||
304
+ name === 'replaceParams' ||
305
+ name === 'pushParams'
306
+ ) {
307
+ throw new Error(`Cannot call ${name} outside a screen`);
308
+ }
252
309
 
253
- const lastEmittedOptionsRef = React.useRef<object | undefined>(undefined);
310
+ withStackTrace(helper, () =>
311
+ // @ts-expect-error name is a valid key, but TypeScript cannot infer it.
312
+ dispatch(CommonActions[name](...args))
313
+ );
314
+ };
315
+
316
+ acc[name] = helper;
317
+
318
+ return acc;
319
+ }, {});
320
+
321
+ const listeners = new WeakMap<
322
+ (...args: never[]) => void,
323
+ EventListenerCallback<NavigationContainerEventMap, 'state'>
324
+ >();
325
+
326
+ return {
327
+ ...helpers,
328
+ dispatch,
329
+ addListener: (type, callback) => {
330
+ if (type === 'state') {
331
+ let listener = listeners.get(callback);
332
+
333
+ if (listener === undefined) {
334
+ // Root's state change events can contain stale and undefined state
335
+ // But navigation objects should only receive non-stale state
336
+ // So we add a wrapper to filter out stale events
337
+ listener = (event) => {
338
+ if (event.data.state?.stale === false) {
339
+ // @ts-expect-error TypeScript doesn't narrow the generic event callback with its type.
340
+ callback(event);
341
+ }
342
+ };
254
343
 
255
- const onOptionsChange = useLatestCallback((options: object) => {
256
- if (lastEmittedOptionsRef.current === options) {
257
- return;
258
- }
344
+ listeners.set(callback, listener);
345
+ }
346
+
347
+ return events.addListener('state', listener);
348
+ }
259
349
 
260
- lastEmittedOptionsRef.current = options;
350
+ return () => {};
351
+ },
352
+ removeListener: (type, callback) => {
353
+ if (type === 'state') {
354
+ const listener = listeners.get(callback);
355
+
356
+ if (listener) {
357
+ events.removeListener('state', listener);
358
+ listeners.delete(callback);
359
+ }
360
+ }
361
+ },
362
+ canGoBack: () =>
363
+ keyedListeners.getNavigation.root?.().canGoBack() ?? false,
364
+ getState: () => keyedListeners.getState.root?.(),
365
+ getParent: (routeName?: string) => {
366
+ if (routeName !== undefined) {
367
+ throw new Error(
368
+ `Couldn't find a navigation object for '${routeName}' because it's called outside a screen. Is your component inside a screen?`
369
+ );
370
+ }
261
371
 
372
+ return undefined;
373
+ },
374
+ setOptions: () => {
375
+ throw new Error('Cannot call setOptions outside a screen');
376
+ },
377
+ isFocused: () => true,
378
+ };
379
+ }, [emitter, keyedListeners, withStackTrace]);
380
+
381
+ React.useImperativeHandle(ref, () => container, [container]);
382
+
383
+ const onDispatchAction = useLatestCallback(
384
+ (action: NavigationAction, noop: boolean) => {
262
385
  emitter.emit({
263
- type: 'options',
264
- data: { options },
386
+ type: '__unsafe_action__',
387
+ data: { action, noop, stack: stackRef.current },
265
388
  });
266
- });
389
+ }
390
+ );
391
+
392
+ const onEmitEvent = useLatestCallback(
393
+ (event: {
394
+ type: string;
395
+ defaultPrevented: boolean | undefined;
396
+ target: string | undefined;
397
+ data: unknown;
398
+ }) => {
399
+ emitter.emit({
400
+ type: '__unsafe_event__',
401
+ data: event,
402
+ });
403
+ }
404
+ );
267
405
 
268
- const stackRef = React.useRef<string | undefined>(undefined);
269
-
270
- const builderContext = React.useMemo(
271
- () => ({
272
- addListener,
273
- addKeyedListener,
274
- onDispatchAction,
275
- onEmitEvent,
276
- onOptionsChange,
277
- scheduleUpdate,
278
- flushUpdates,
279
- stackRef,
280
- }),
281
- [
282
- addListener,
283
- addKeyedListener,
284
- onDispatchAction,
285
- onEmitEvent,
286
- onOptionsChange,
287
- scheduleUpdate,
288
- flushUpdates,
289
- ]
290
- );
406
+ const isOptionsListenerReadyRef = React.useRef(false);
407
+ const lastEmittedOptionsRef = React.useRef<object | undefined>(undefined);
291
408
 
292
- const isInitialRef = React.useRef(true);
293
-
294
- const getIsInitial = React.useCallback(() => isInitialRef.current, []);
295
-
296
- const context = React.useMemo(
297
- () => ({
298
- state,
299
- getState,
300
- setState,
301
- getKey,
302
- setKey,
303
- getIsInitial,
304
- addOptionsGetter,
305
- }),
306
- [
307
- state,
308
- getState,
309
- setState,
310
- getKey,
311
- setKey,
312
- getIsInitial,
313
- addOptionsGetter,
314
- ]
315
- );
409
+ const onOptionsChange = useLatestCallback(() => {
410
+ if (!isOptionsListenerReadyRef.current) {
411
+ return;
412
+ }
316
413
 
317
- const onReadyRef = React.useRef(onReady);
318
- const onStateChangeRef = React.useRef(onStateChange);
414
+ const options = getCurrentOptions();
319
415
 
320
- React.useEffect(() => {
321
- isInitialRef.current = false;
322
- onStateChangeRef.current = onStateChange;
323
- onReadyRef.current = onReady;
324
- });
416
+ if (options == null || lastEmittedOptionsRef.current === options) {
417
+ return;
418
+ }
325
419
 
326
- const onReadyCalledRef = React.useRef(false);
420
+ lastEmittedOptionsRef.current = options;
327
421
 
328
- React.useEffect(() => {
329
- if (!onReadyCalledRef.current && isReady()) {
330
- onReadyCalledRef.current = true;
331
- onReadyRef.current?.();
332
- emitter.emit({ type: 'ready' });
333
- }
334
- }, [state, isReady, emitter]);
422
+ emitter.emit({
423
+ type: 'options',
424
+ data: { options },
425
+ });
426
+ });
427
+
428
+ React.useEffect(() => {
429
+ isOptionsListenerReadyRef.current = true;
430
+
431
+ onOptionsChange();
432
+
433
+ return () => {
434
+ isOptionsListenerReadyRef.current = false;
435
+ };
436
+ }, [onOptionsChange]);
437
+
438
+ const lastEmittedStateRef = React.useRef<State>(undefined);
439
+
440
+ const getIsStateEmitted = useLatestCallback(
441
+ () => !isFirstMountRef.current && lastEmittedStateRef.current === getState()
442
+ );
443
+
444
+ const builderContext = React.useMemo(
445
+ () => ({
446
+ addListener,
447
+ addKeyedListener,
448
+ onDispatchAction,
449
+ onEmitEvent,
450
+ onOptionsChange,
451
+ getIsStateEmitted,
452
+ scheduleUpdate,
453
+ flushUpdates,
454
+ withStackTrace,
455
+ }),
456
+ [
457
+ addListener,
458
+ addKeyedListener,
459
+ onDispatchAction,
460
+ onEmitEvent,
461
+ onOptionsChange,
462
+ getIsStateEmitted,
463
+ scheduleUpdate,
464
+ flushUpdates,
465
+ withStackTrace,
466
+ ]
467
+ );
468
+
469
+ const isInitialRef = React.useRef(true);
470
+
471
+ const getIsInitial = React.useCallback(() => isInitialRef.current, []);
472
+
473
+ const context = React.useMemo(
474
+ () => ({
475
+ state,
476
+ getState,
477
+ setState,
478
+ subscribe,
479
+ getKey,
480
+ setKey,
481
+ getIsInitial,
482
+ addOptionsGetter,
483
+ }),
484
+ [
485
+ state,
486
+ getState,
487
+ setState,
488
+ subscribe,
489
+ getKey,
490
+ setKey,
491
+ getIsInitial,
492
+ addOptionsGetter,
493
+ ]
494
+ );
495
+
496
+ const onReadyRef = React.useRef(onReady);
497
+ const onStateChangeRef = React.useRef(onStateChange);
498
+
499
+ React.useEffect(() => {
500
+ isInitialRef.current = false;
501
+ onStateChangeRef.current = onStateChange;
502
+ onReadyRef.current = onReady;
503
+ });
504
+
505
+ const onReadyCalledRef = React.useRef(false);
506
+
507
+ React.useEffect(() => {
508
+ if (!onReadyCalledRef.current && isReady()) {
509
+ onReadyCalledRef.current = true;
510
+ onReadyRef.current?.();
511
+ emitter.emit({ type: 'ready' });
512
+ }
513
+ }, [state, isReady, emitter]);
335
514
 
336
- React.useEffect(() => {
515
+ React.useEffect(() => {
516
+ if (process.env.NODE_ENV !== 'production') {
337
517
  const hydratedState = getRootState();
338
518
 
339
- if (process.env.NODE_ENV !== 'production') {
340
- if (hydratedState !== undefined) {
341
- const serializableResult = checkSerializable(hydratedState);
342
-
343
- if (!serializableResult.serializable) {
344
- const { location, reason } = serializableResult;
345
-
346
- let path = '';
347
- let pointer: Record<any, any> = hydratedState;
348
- let params = false;
349
-
350
- for (let i = 0; i < location.length; i++) {
351
- const curr = location[i];
352
- const prev = location[i - 1];
353
-
354
- pointer = pointer[curr];
355
-
356
- if (!params && curr === 'state') {
357
- continue;
358
- } else if (!params && curr === 'routes') {
359
- if (path) {
360
- path += ' > ';
361
- }
362
- } else if (
363
- !params &&
364
- typeof curr === 'number' &&
365
- prev === 'routes'
366
- ) {
367
- path += pointer?.name;
368
- } else if (!params) {
369
- path += ` > ${curr}`;
370
- params = true;
371
- } else {
372
- if (typeof curr === 'number' || /^[0-9]+$/.test(curr)) {
373
- path += `[${curr}]`;
374
- } else if (/^[a-z$_]+$/i.test(curr)) {
375
- path += `.${curr}`;
376
- } else {
377
- path += `[${JSON.stringify(curr)}]`;
378
- }
379
- }
380
- }
381
-
382
- const message = `Non-serializable values were found in the navigation state. Check:\n\n${path} (${reason})\n\nThis can break usage such as persisting and restoring state. This might happen if you passed non-serializable values such as function, class instances etc. in params. If you need to use components with callbacks in your options, you can use 'navigation.setOptions' instead. See https://reactnavigation.org/docs/troubleshooting#i-get-the-warning-non-serializable-values-were-found-in-the-navigation-state for more details.`;
383
-
384
- if (!serializableWarnings.includes(message)) {
385
- serializableWarnings.push(message);
386
- console.warn(message);
387
- }
388
- }
389
-
390
- const duplicateRouteNamesResult =
391
- checkDuplicateRouteNames(hydratedState);
519
+ if (hydratedState !== undefined) {
520
+ const duplicateRouteNamesResult =
521
+ checkDuplicateRouteNames(hydratedState);
392
522
 
393
- if (duplicateRouteNamesResult.length) {
394
- const message = `Found screens with the same name nested inside one another. Check:\n${duplicateRouteNamesResult.map(
395
- (locations) => `\n${locations.join(', ')}`
396
- )}\n\nThis can cause confusing behavior during navigation. Consider using unique names for each screen instead.`;
523
+ if (duplicateRouteNamesResult.length) {
524
+ const message = `Found screens with the same name nested inside one another. Check:\n${duplicateRouteNamesResult.map(
525
+ (locations) => `\n${locations.join(', ')}`
526
+ )}\n\nThis can cause confusing behavior during navigation. Consider using unique names for each screen instead.`;
397
527
 
398
- if (!duplicateNameWarnings.includes(message)) {
399
- duplicateNameWarnings.push(message);
400
- console.warn(message);
401
- }
402
- }
528
+ warnOnce(true, message);
403
529
  }
404
530
  }
531
+ }
405
532
 
406
- emitter.emit({ type: 'state', data: { state } });
533
+ lastEmittedStateRef.current = state;
407
534
 
408
- if (!isFirstMountRef.current && onStateChangeRef.current) {
409
- onStateChangeRef.current(hydratedState);
410
- }
535
+ emitter.emit({ type: 'state', data: { state } });
411
536
 
412
- isFirstMountRef.current = false;
413
- }, [getRootState, emitter, state]);
537
+ if (!isFirstMountRef.current && onStateChangeRef.current) {
538
+ const hydratedState = getRootState();
414
539
 
415
- const defaultOnUnhandledAction = useLatestCallback(
416
- (action: NavigationAction) => {
417
- if (process.env.NODE_ENV === 'production') {
418
- return;
419
- }
540
+ onStateChangeRef.current(hydratedState);
541
+ }
420
542
 
421
- const payload: Record<string, any> | undefined = action.payload;
422
-
423
- let message = `The action '${action.type}'${
424
- payload ? ` with payload ${JSON.stringify(action.payload)}` : ''
425
- } was not handled by any navigator.`;
426
-
427
- switch (action.type) {
428
- case 'PRELOAD':
429
- case 'NAVIGATE':
430
- case 'PUSH':
431
- case 'REPLACE':
432
- case 'POP_TO':
433
- case 'JUMP_TO':
434
- if (payload?.name) {
435
- message += `\n\nDo you have a screen named '${payload.name}'?\n\nIf you're trying to navigate to a screen in a nested navigator, see https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator.\n\nIf you're using conditional rendering, navigation will happen automatically and you shouldn't navigate manually, see.`;
436
- } else {
437
- message += `\n\nYou need to pass the name of the screen to navigate to.\n\nSee https://reactnavigation.org/docs/navigation-actions for usage.`;
438
- }
439
-
440
- break;
441
- case 'GO_BACK':
442
- case 'POP':
443
- case 'POP_TO_TOP':
444
- message += `\n\nIs there any screen to go back to?`;
445
- break;
446
- case 'OPEN_DRAWER':
447
- case 'CLOSE_DRAWER':
448
- case 'TOGGLE_DRAWER':
449
- message += `\n\nIs your screen inside a Drawer navigator?`;
450
- break;
451
- }
543
+ isFirstMountRef.current = false;
544
+ }, [getRootState, emitter, state]);
545
+
546
+ const defaultOnUnhandledAction = useLatestCallback(
547
+ (action: NavigationAction) => {
548
+ if (process.env.NODE_ENV === 'production') {
549
+ return;
550
+ }
452
551
 
453
- message += `\n\nThis is a development-only warning and won't be shown in production.`;
552
+ const payload: Record<string, any> | undefined = action.payload;
553
+
554
+ let message = `The action '${action.type}'${
555
+ payload ? ` with payload ${JSON.stringify(action.payload)}` : ''
556
+ } was not handled by any navigator.`;
557
+
558
+ switch (action.type) {
559
+ case 'PRELOAD':
560
+ case 'NAVIGATE':
561
+ case 'PUSH':
562
+ case 'REPLACE':
563
+ case 'POP_TO':
564
+ case 'JUMP_TO':
565
+ if (payload?.name) {
566
+ message += `\n\nDo you have a screen named '${payload.name}'?\n\nIf you're trying to navigate to a screen in a nested navigator, see https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator.\n\nIf you're using conditional rendering, navigation will happen automatically and you shouldn't navigate manually, see.`;
567
+ } else {
568
+ message += `\n\nYou need to pass the name of the screen to navigate to.\n\nSee https://reactnavigation.org/docs/navigation-actions for usage.`;
569
+ }
454
570
 
455
- console.error(message);
571
+ break;
572
+ case 'GO_BACK':
573
+ case 'POP':
574
+ case 'POP_TO_TOP':
575
+ case 'DISMISS':
576
+ message += `\n\nIs there any screen to go back to?`;
577
+ break;
578
+ case 'OPEN_DRAWER':
579
+ case 'CLOSE_DRAWER':
580
+ case 'TOGGLE_DRAWER':
581
+ message += `\n\nIs your screen inside a Drawer navigator?`;
582
+ break;
456
583
  }
457
- );
458
584
 
459
- return (
460
- <NavigationIndependentTreeContext.Provider value={false}>
461
- <NavigationContainerRefContext.Provider value={navigation}>
585
+ message += `\n\nThis is a development-only warning and won't be shown in production.`;
586
+
587
+ console.error(message);
588
+ }
589
+ );
590
+
591
+ return (
592
+ <NavigationIndependentTreeContext.Provider value={false}>
593
+ <NavigationContainerRefContext.Provider value={container}>
594
+ <NavigationRootContext.Provider value={navigation}>
462
595
  <NavigationBuilderContext.Provider value={builderContext}>
463
596
  <NavigationStateContext.Provider value={context}>
464
- <UnhandledActionContext.Provider
465
- value={onUnhandledAction ?? defaultOnUnhandledAction}
466
- >
467
- <EnsureSingleNavigator>
468
- <ThemeProvider value={theme}>{children}</ThemeProvider>
469
- </EnsureSingleNavigator>
470
- </UnhandledActionContext.Provider>
597
+ <ConsumedParamsContext.Provider value={consumedParams}>
598
+ <UnhandledActionContext.Provider
599
+ value={onUnhandledAction ?? defaultOnUnhandledAction}
600
+ >
601
+ <EnsureSingleNavigator>
602
+ <ThemeProvider value={theme}>{children}</ThemeProvider>
603
+ </EnsureSingleNavigator>
604
+ </UnhandledActionContext.Provider>
605
+ </ConsumedParamsContext.Provider>
471
606
  </NavigationStateContext.Provider>
472
607
  </NavigationBuilderContext.Provider>
473
- </NavigationContainerRefContext.Provider>
474
- </NavigationIndependentTreeContext.Provider>
475
- );
476
- }
477
- );
608
+ </NavigationRootContext.Provider>
609
+ </NavigationContainerRefContext.Provider>
610
+ </NavigationIndependentTreeContext.Provider>
611
+ );
612
+ }