@react-navigation/core 7.0.3 → 7.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/BaseNavigationContainer.js +9 -2
- package/lib/commonjs/BaseNavigationContainer.js.map +1 -1
- package/lib/commonjs/NavigationBuilderContext.js +3 -0
- package/lib/commonjs/NavigationBuilderContext.js.map +1 -1
- package/lib/commonjs/StaticNavigation.js +1 -1
- package/lib/commonjs/StaticNavigation.js.map +1 -1
- package/lib/commonjs/useDescriptors.js +3 -1
- package/lib/commonjs/useDescriptors.js.map +1 -1
- package/lib/commonjs/useNavigationBuilder.js +5 -11
- package/lib/commonjs/useNavigationBuilder.js.map +1 -1
- package/lib/commonjs/useScheduleUpdate.js +29 -0
- package/lib/commonjs/useScheduleUpdate.js.map +1 -0
- package/lib/commonjs/useSyncState.js +9 -9
- package/lib/commonjs/useSyncState.js.map +1 -1
- package/lib/module/BaseNavigationContainer.js +9 -2
- package/lib/module/BaseNavigationContainer.js.map +1 -1
- package/lib/module/NavigationBuilderContext.js +3 -0
- package/lib/module/NavigationBuilderContext.js.map +1 -1
- package/lib/module/StaticNavigation.js +1 -1
- package/lib/module/StaticNavigation.js.map +1 -1
- package/lib/module/useDescriptors.js +3 -1
- package/lib/module/useDescriptors.js.map +1 -1
- package/lib/module/useNavigationBuilder.js +5 -11
- package/lib/module/useNavigationBuilder.js.map +1 -1
- package/lib/module/useScheduleUpdate.js +23 -0
- package/lib/module/useScheduleUpdate.js.map +1 -0
- package/lib/module/useSyncState.js +9 -9
- package/lib/module/useSyncState.js.map +1 -1
- package/lib/typescript/commonjs/src/BaseNavigationContainer.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/NavigationBuilderContext.d.ts +1 -0
- package/lib/typescript/commonjs/src/NavigationBuilderContext.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/useDescriptors.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/useNavigationBuilder.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/useScheduleUpdate.d.ts +9 -0
- package/lib/typescript/commonjs/src/useScheduleUpdate.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/useSyncState.d.ts +7 -1
- package/lib/typescript/commonjs/src/useSyncState.d.ts.map +1 -1
- package/lib/typescript/commonjs/tsconfig.build.tsbuildinfo +1 -1
- package/lib/typescript/module/src/BaseNavigationContainer.d.ts.map +1 -1
- package/lib/typescript/module/src/NavigationBuilderContext.d.ts +1 -0
- package/lib/typescript/module/src/NavigationBuilderContext.d.ts.map +1 -1
- package/lib/typescript/module/src/useDescriptors.d.ts.map +1 -1
- package/lib/typescript/module/src/useNavigationBuilder.d.ts.map +1 -1
- package/lib/typescript/module/src/useScheduleUpdate.d.ts +9 -0
- package/lib/typescript/module/src/useScheduleUpdate.d.ts.map +1 -0
- package/lib/typescript/module/src/useSyncState.d.ts +7 -1
- package/lib/typescript/module/src/useSyncState.d.ts.map +1 -1
- package/lib/typescript/module/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/src/BaseNavigationContainer.tsx +6 -3
- package/src/NavigationBuilderContext.tsx +4 -0
- package/src/useDescriptors.tsx +9 -2
- package/src/useNavigationBuilder.tsx +4 -9
- package/src/useScheduleUpdate.tsx +21 -0
- package/src/useSyncState.tsx +9 -10
|
@@ -103,9 +103,10 @@ export const BaseNavigationContainer = React.forwardRef(
|
|
|
103
103
|
);
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
const
|
|
107
|
-
() =>
|
|
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
|
});
|
package/src/useDescriptors.tsx
CHANGED
|
@@ -116,8 +116,13 @@ export function useDescriptors<
|
|
|
116
116
|
const [options, setOptions] = React.useState<Record<string, ScreenOptions>>(
|
|
117
117
|
{}
|
|
118
118
|
);
|
|
119
|
-
const {
|
|
120
|
-
|
|
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
|
-
|
|
565
|
+
useScheduleUpdate(() => {
|
|
568
566
|
if (shouldUpdate) {
|
|
569
567
|
// If the state needs to be updated, we'll schedule an update
|
|
570
|
-
|
|
571
|
-
scheduleUpdate(() => {
|
|
572
|
-
setState(nextState);
|
|
573
|
-
});
|
|
568
|
+
setState(nextState);
|
|
574
569
|
}
|
|
575
570
|
});
|
|
576
571
|
|
|
@@ -614,7 +609,7 @@ export function useNavigationBuilder<
|
|
|
614
609
|
|
|
615
610
|
useIsomorphicLayoutEffect(() => {
|
|
616
611
|
stateRef.current = null;
|
|
617
|
-
}
|
|
612
|
+
});
|
|
618
613
|
|
|
619
614
|
const getState = useLatestCallback((): State => {
|
|
620
615
|
if (stateRef.current != null) {
|
|
@@ -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
|
+
}
|
package/src/useSyncState.tsx
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
98
|
+
return {
|
|
99
|
+
state,
|
|
100
|
+
getState: store.getState,
|
|
101
|
+
setState: store.setState,
|
|
102
|
+
scheduleUpdate,
|
|
103
|
+
flushUpdates,
|
|
104
|
+
} as const;
|
|
106
105
|
}
|