@react-navigation/core 7.0.3 → 7.0.4

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 (55) hide show
  1. package/lib/commonjs/BaseNavigationContainer.js +9 -2
  2. package/lib/commonjs/BaseNavigationContainer.js.map +1 -1
  3. package/lib/commonjs/NavigationBuilderContext.js +3 -0
  4. package/lib/commonjs/NavigationBuilderContext.js.map +1 -1
  5. package/lib/commonjs/StaticNavigation.js +1 -1
  6. package/lib/commonjs/StaticNavigation.js.map +1 -1
  7. package/lib/commonjs/useDescriptors.js +3 -1
  8. package/lib/commonjs/useDescriptors.js.map +1 -1
  9. package/lib/commonjs/useNavigationBuilder.js +4 -10
  10. package/lib/commonjs/useNavigationBuilder.js.map +1 -1
  11. package/lib/commonjs/useScheduleUpdate.js +29 -0
  12. package/lib/commonjs/useScheduleUpdate.js.map +1 -0
  13. package/lib/commonjs/useSyncState.js +9 -9
  14. package/lib/commonjs/useSyncState.js.map +1 -1
  15. package/lib/module/BaseNavigationContainer.js +9 -2
  16. package/lib/module/BaseNavigationContainer.js.map +1 -1
  17. package/lib/module/NavigationBuilderContext.js +3 -0
  18. package/lib/module/NavigationBuilderContext.js.map +1 -1
  19. package/lib/module/StaticNavigation.js +1 -1
  20. package/lib/module/StaticNavigation.js.map +1 -1
  21. package/lib/module/useDescriptors.js +3 -1
  22. package/lib/module/useDescriptors.js.map +1 -1
  23. package/lib/module/useNavigationBuilder.js +4 -10
  24. package/lib/module/useNavigationBuilder.js.map +1 -1
  25. package/lib/module/useScheduleUpdate.js +23 -0
  26. package/lib/module/useScheduleUpdate.js.map +1 -0
  27. package/lib/module/useSyncState.js +9 -9
  28. package/lib/module/useSyncState.js.map +1 -1
  29. package/lib/typescript/commonjs/src/BaseNavigationContainer.d.ts.map +1 -1
  30. package/lib/typescript/commonjs/src/NavigationBuilderContext.d.ts +1 -0
  31. package/lib/typescript/commonjs/src/NavigationBuilderContext.d.ts.map +1 -1
  32. package/lib/typescript/commonjs/src/useDescriptors.d.ts.map +1 -1
  33. package/lib/typescript/commonjs/src/useNavigationBuilder.d.ts.map +1 -1
  34. package/lib/typescript/commonjs/src/useScheduleUpdate.d.ts +9 -0
  35. package/lib/typescript/commonjs/src/useScheduleUpdate.d.ts.map +1 -0
  36. package/lib/typescript/commonjs/src/useSyncState.d.ts +7 -1
  37. package/lib/typescript/commonjs/src/useSyncState.d.ts.map +1 -1
  38. package/lib/typescript/commonjs/tsconfig.build.tsbuildinfo +1 -1
  39. package/lib/typescript/module/src/BaseNavigationContainer.d.ts.map +1 -1
  40. package/lib/typescript/module/src/NavigationBuilderContext.d.ts +1 -0
  41. package/lib/typescript/module/src/NavigationBuilderContext.d.ts.map +1 -1
  42. package/lib/typescript/module/src/useDescriptors.d.ts.map +1 -1
  43. package/lib/typescript/module/src/useNavigationBuilder.d.ts.map +1 -1
  44. package/lib/typescript/module/src/useScheduleUpdate.d.ts +9 -0
  45. package/lib/typescript/module/src/useScheduleUpdate.d.ts.map +1 -0
  46. package/lib/typescript/module/src/useSyncState.d.ts +7 -1
  47. package/lib/typescript/module/src/useSyncState.d.ts.map +1 -1
  48. package/lib/typescript/module/tsconfig.build.tsbuildinfo +1 -1
  49. package/package.json +6 -6
  50. package/src/BaseNavigationContainer.tsx +6 -3
  51. package/src/NavigationBuilderContext.tsx +4 -0
  52. package/src/useDescriptors.tsx +9 -2
  53. package/src/useNavigationBuilder.tsx +3 -8
  54. package/src/useScheduleUpdate.tsx +21 -0
  55. package/src/useSyncState.tsx +9 -10
@@ -103,9 +103,10 @@ export const BaseNavigationContainer = React.forwardRef(
103
103
  );
104
104
  }
105
105
 
106
- const [state, getState, setState, scheduleUpdate] = useSyncState<State>(
107
- () => getPartialState(initialState == null ? undefined : initialState)
108
- );
106
+ const { state, getState, setState, scheduleUpdate, flushUpdates } =
107
+ useSyncState<State>(() =>
108
+ getPartialState(initialState == null ? undefined : initialState)
109
+ );
109
110
 
110
111
  const isFirstMountRef = React.useRef<boolean>(true);
111
112
 
@@ -261,6 +262,7 @@ export const BaseNavigationContainer = React.forwardRef(
261
262
  onDispatchAction,
262
263
  onOptionsChange,
263
264
  scheduleUpdate,
265
+ flushUpdates,
264
266
  stackRef,
265
267
  }),
266
268
  [
@@ -269,6 +271,7 @@ export const BaseNavigationContainer = React.forwardRef(
269
271
  onDispatchAction,
270
272
  onOptionsChange,
271
273
  scheduleUpdate,
274
+ flushUpdates,
272
275
  ]
273
276
  );
274
277
 
@@ -62,6 +62,7 @@ export const NavigationBuilderContext = React.createContext<{
62
62
  onDispatchAction: (action: NavigationAction, noop: boolean) => void;
63
63
  onOptionsChange: (options: object) => void;
64
64
  scheduleUpdate: (callback: () => void) => void;
65
+ flushUpdates: () => void;
65
66
  stackRef?: React.MutableRefObject<string | undefined>;
66
67
  }>({
67
68
  onDispatchAction: () => undefined,
@@ -69,4 +70,7 @@ export const NavigationBuilderContext = React.createContext<{
69
70
  scheduleUpdate: () => {
70
71
  throw new Error("Couldn't find a context for scheduling updates.");
71
72
  },
73
+ flushUpdates: () => {
74
+ throw new Error("Couldn't find a context for flushing updates.");
75
+ },
72
76
  });
@@ -116,8 +116,13 @@ export function useDescriptors<
116
116
  const [options, setOptions] = React.useState<Record<string, ScreenOptions>>(
117
117
  {}
118
118
  );
119
- const { onDispatchAction, onOptionsChange, scheduleUpdate, stackRef } =
120
- React.useContext(NavigationBuilderContext);
119
+ const {
120
+ onDispatchAction,
121
+ onOptionsChange,
122
+ scheduleUpdate,
123
+ flushUpdates,
124
+ stackRef,
125
+ } = React.useContext(NavigationBuilderContext);
121
126
 
122
127
  const context = React.useMemo(
123
128
  () => ({
@@ -129,6 +134,7 @@ export function useDescriptors<
129
134
  onDispatchAction,
130
135
  onOptionsChange,
131
136
  scheduleUpdate,
137
+ flushUpdates,
132
138
  stackRef,
133
139
  }),
134
140
  [
@@ -140,6 +146,7 @@ export function useDescriptors<
140
146
  onDispatchAction,
141
147
  onOptionsChange,
142
148
  scheduleUpdate,
149
+ flushUpdates,
143
150
  stackRef,
144
151
  ]
145
152
  );
@@ -18,7 +18,6 @@ import { deepFreeze } from './deepFreeze';
18
18
  import { Group } from './Group';
19
19
  import { isArrayEqual } from './isArrayEqual';
20
20
  import { isRecordEqual } from './isRecordEqual';
21
- import { NavigationBuilderContext } from './NavigationBuilderContext';
22
21
  import { NavigationHelpersContext } from './NavigationHelpersContext';
23
22
  import { NavigationRouteContext } from './NavigationRouteContext';
24
23
  import { NavigationStateContext } from './NavigationStateContext';
@@ -47,6 +46,7 @@ import { useOnAction } from './useOnAction';
47
46
  import { useOnGetState } from './useOnGetState';
48
47
  import { useOnRouteFocus } from './useOnRouteFocus';
49
48
  import { useRegisterNavigator } from './useRegisterNavigator';
49
+ import { useScheduleUpdate } from './useScheduleUpdate';
50
50
 
51
51
  // This is to make TypeScript compiler happy
52
52
  PrivateValueStore;
@@ -560,17 +560,12 @@ export function useNavigationBuilder<
560
560
  : nextState;
561
561
  }
562
562
 
563
- const { scheduleUpdate } = React.useContext(NavigationBuilderContext);
564
-
565
563
  const shouldUpdate = state !== nextState;
566
564
 
567
- useIsomorphicLayoutEffect(() => {
565
+ useScheduleUpdate(() => {
568
566
  if (shouldUpdate) {
569
567
  // If the state needs to be updated, we'll schedule an update
570
- // These updates will be batched and run in the reverse order
571
- scheduleUpdate(() => {
572
- setState(nextState);
573
- });
568
+ setState(nextState);
574
569
  }
575
570
  });
576
571
 
@@ -0,0 +1,21 @@
1
+ import * as React from 'react';
2
+
3
+ import { NavigationBuilderContext } from './NavigationBuilderContext';
4
+ /**
5
+ * When screen config changes, we want to update the navigator in the same update phase.
6
+ * However, navigation state is in the root component and React won't let us update it from a child.
7
+ * This is a workaround for that, the scheduled update is stored in the ref without actually calling setState.
8
+ * It lets all subsequent updates access the latest state so it stays correct.
9
+ * Then we call setState during after the component updates.
10
+ */
11
+ export function useScheduleUpdate(callback: () => void) {
12
+ const { scheduleUpdate, flushUpdates } = React.useContext(
13
+ NavigationBuilderContext
14
+ );
15
+
16
+ // FIXME: This is potentially unsafe
17
+ // However, since we are using sync store, it might be fine
18
+ scheduleUpdate(callback);
19
+
20
+ React.useEffect(flushUpdates);
21
+ }
@@ -2,7 +2,6 @@ import * as React from 'react';
2
2
  import useLatestCallback from 'use-latest-callback';
3
3
 
4
4
  import { deepFreeze } from './deepFreeze';
5
- import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect';
6
5
 
7
6
  const createStore = <T,>(getInitialState: () => T) => {
8
7
  const listeners: (() => void)[] = [];
@@ -81,8 +80,7 @@ export function useSyncState<T>(getInitialState: () => T) {
81
80
  pendingUpdatesRef.current.push(callback);
82
81
  });
83
82
 
84
- useIsomorphicLayoutEffect(() => {
85
- // Flush all the pending updates
83
+ const flushUpdates = useLatestCallback(() => {
86
84
  const pendingUpdates = pendingUpdatesRef.current;
87
85
 
88
86
  pendingUpdatesRef.current = [];
@@ -90,17 +88,18 @@ export function useSyncState<T>(getInitialState: () => T) {
90
88
  if (pendingUpdates.length !== 0) {
91
89
  store.batchUpdates(() => {
92
90
  // Flush all the pending updates
93
- // These updates should be scheduled in useEffect
94
- // Run them in reverse order so that the deepest updates are run last
95
- // This is opposite to useEffect where the deepest effects are run first
96
- for (let i = pendingUpdates.length - 1; i >= 0; i--) {
97
- const update = pendingUpdates[i];
98
-
91
+ for (const update of pendingUpdates) {
99
92
  update();
100
93
  }
101
94
  });
102
95
  }
103
96
  });
104
97
 
105
- return [state, store.getState, store.setState, scheduleUpdate] as const;
98
+ return {
99
+ state,
100
+ getState: store.getState,
101
+ setState: store.setState,
102
+ scheduleUpdate,
103
+ flushUpdates,
104
+ } as const;
106
105
  }