@react-navigation/native 7.2.5 → 7.3.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.
- package/lib/module/NavigationContainer.js +9 -44
- package/lib/module/NavigationContainer.js.map +1 -1
- package/lib/module/UnhandledLinkingContext.js +9 -7
- package/lib/module/UnhandledLinkingContext.js.map +1 -1
- package/lib/module/createStandardNavigationFactories.js +97 -0
- package/lib/module/createStandardNavigationFactories.js.map +1 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/useLinking.js +2 -7
- package/lib/module/useLinking.js.map +1 -1
- package/lib/module/useLinking.native.js +14 -14
- package/lib/module/useLinking.native.js.map +1 -1
- package/lib/module/useMemoArray.js +25 -0
- package/lib/module/useMemoArray.js.map +1 -0
- package/lib/typescript/src/Link.d.ts +1 -1
- package/lib/typescript/src/Link.d.ts.map +1 -1
- package/lib/typescript/src/LinkingContext.d.ts +1 -1
- package/lib/typescript/src/LinkingContext.d.ts.map +1 -1
- package/lib/typescript/src/LocaleDirContext.d.ts +1 -1
- package/lib/typescript/src/LocaleDirContext.d.ts.map +1 -1
- package/lib/typescript/src/NavigationContainer.d.ts +1 -1
- package/lib/typescript/src/NavigationContainer.d.ts.map +1 -1
- package/lib/typescript/src/ServerContainer.d.ts +2 -2
- package/lib/typescript/src/ServerContainer.d.ts.map +1 -1
- package/lib/typescript/src/UnhandledLinkingContext.d.ts +6 -0
- package/lib/typescript/src/UnhandledLinkingContext.d.ts.map +1 -1
- package/lib/typescript/src/createStandardNavigationFactories.d.ts +47 -0
- package/lib/typescript/src/createStandardNavigationFactories.d.ts.map +1 -0
- package/lib/typescript/src/createStaticNavigation.d.ts +2 -2
- package/lib/typescript/src/createStaticNavigation.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +17 -16
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/useDocumentTitle.d.ts +1 -1
- package/lib/typescript/src/useDocumentTitle.d.ts.map +1 -1
- package/lib/typescript/src/useLinkBuilder.d.ts.map +1 -1
- package/lib/typescript/src/useLinking.d.ts +2 -2
- package/lib/typescript/src/useLinking.d.ts.map +1 -1
- package/lib/typescript/src/useLinking.native.d.ts +2 -2
- package/lib/typescript/src/useLinking.native.d.ts.map +1 -1
- package/lib/typescript/src/useLocale.d.ts +1 -1
- package/lib/typescript/src/useMemoArray.d.ts +2 -0
- package/lib/typescript/src/useMemoArray.d.ts.map +1 -0
- package/package.json +5 -4
- package/src/NavigationContainer.tsx +15 -62
- package/src/UnhandledLinkingContext.tsx +8 -9
- package/src/createStandardNavigationFactories.tsx +294 -0
- package/src/index.tsx +5 -0
- package/src/useLinking.native.tsx +30 -29
- package/src/useLinking.tsx +2 -14
- package/src/useMemoArray.tsx +41 -0
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CommonActions,
|
|
3
|
+
createNavigatorFactory,
|
|
4
|
+
createScreenFactory,
|
|
5
|
+
type DefaultNavigatorOptions,
|
|
6
|
+
type DefaultRouterOptions,
|
|
7
|
+
type EventMapBase,
|
|
8
|
+
type NavigationAction,
|
|
9
|
+
type NavigationProp,
|
|
10
|
+
type NavigatorTypeBagBase,
|
|
11
|
+
type ParamListBase,
|
|
12
|
+
type RouterFactory,
|
|
13
|
+
type StaticConfig,
|
|
14
|
+
type StaticParamList,
|
|
15
|
+
type StaticScreenFactory,
|
|
16
|
+
type TypedNavigator,
|
|
17
|
+
useNavigationBuilder,
|
|
18
|
+
} from '@react-navigation/core';
|
|
19
|
+
import * as React from 'react';
|
|
20
|
+
import type {
|
|
21
|
+
createStandardNavigator,
|
|
22
|
+
NavigatorArgs as StandardNavigationArgs,
|
|
23
|
+
} from 'standard-navigation';
|
|
24
|
+
|
|
25
|
+
import { useBuildHref } from './useLinkBuilder';
|
|
26
|
+
import { useMemoArray } from './useMemoArray';
|
|
27
|
+
|
|
28
|
+
type StandardEventMap<EventMap extends EventMapBase> = {
|
|
29
|
+
[EventName in keyof EventMap]: {
|
|
30
|
+
data: EventMap[EventName] extends { data?: infer Data }
|
|
31
|
+
? Data extends object | undefined
|
|
32
|
+
? Data
|
|
33
|
+
: object | undefined
|
|
34
|
+
: undefined;
|
|
35
|
+
canPreventDefault: EventMap[EventName] extends { canPreventDefault: true }
|
|
36
|
+
? true
|
|
37
|
+
: false;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
type ActionHelpersOf<T> =
|
|
42
|
+
T extends Record<string, (...args: never[]) => unknown> ? T : {};
|
|
43
|
+
|
|
44
|
+
type StandardNavigationNavigatorProps<
|
|
45
|
+
TypeBag extends StandardNavigationTypeBagBase,
|
|
46
|
+
> = TypeBag['RouterOptions'] &
|
|
47
|
+
DefaultNavigatorOptions<
|
|
48
|
+
ParamListBase,
|
|
49
|
+
string | undefined,
|
|
50
|
+
StandardNavigationTypeBagFor<TypeBag, ParamListBase>['State'],
|
|
51
|
+
TypeBag['ScreenOptions'],
|
|
52
|
+
TypeBag['EventMap'],
|
|
53
|
+
StandardNavigation<TypeBag>
|
|
54
|
+
>;
|
|
55
|
+
|
|
56
|
+
type StandardNavigationTypeBagFor<
|
|
57
|
+
TypeBag extends StandardNavigationTypeBagBase,
|
|
58
|
+
ParamList extends ParamListBase,
|
|
59
|
+
NavigatorID extends string | undefined = string | undefined,
|
|
60
|
+
> = TypeBag & {
|
|
61
|
+
ParamList: ParamList;
|
|
62
|
+
NavigatorID: NavigatorID;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
type StandardNavigation<TypeBag extends StandardNavigationTypeBagBase> =
|
|
66
|
+
StandardNavigationTypeBagFor<
|
|
67
|
+
TypeBag,
|
|
68
|
+
ParamListBase
|
|
69
|
+
>['NavigationList'][keyof StandardNavigationTypeBagFor<
|
|
70
|
+
TypeBag,
|
|
71
|
+
ParamListBase
|
|
72
|
+
>['NavigationList']];
|
|
73
|
+
|
|
74
|
+
type StandardNavigationPropsMapper<
|
|
75
|
+
TypeBag extends StandardNavigationTypeBagBase,
|
|
76
|
+
NavigatorProps extends object,
|
|
77
|
+
> = (props: {
|
|
78
|
+
state: StandardNavigationTypeBagFor<TypeBag, ParamListBase>['State'];
|
|
79
|
+
navigation: StandardNavigation<TypeBag>;
|
|
80
|
+
}) => Partial<NavigatorProps>;
|
|
81
|
+
|
|
82
|
+
type StandardNavigationDefaultBag<
|
|
83
|
+
TypeBag extends StandardNavigationTypeBagBase,
|
|
84
|
+
> = StandardNavigationTypeBagFor<TypeBag, ParamListBase, string | undefined>;
|
|
85
|
+
|
|
86
|
+
type StandardNavigationFactories<
|
|
87
|
+
TypeBag extends StandardNavigationTypeBagBase,
|
|
88
|
+
> = {
|
|
89
|
+
createNavigator: StandardNavigationCreateNavigator<TypeBag>;
|
|
90
|
+
createScreen: StaticScreenFactory<StandardNavigationDefaultBag<TypeBag>>;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export type StandardNavigationCreateNavigator<
|
|
94
|
+
TypeBag extends StandardNavigationTypeBagBase,
|
|
95
|
+
> = {
|
|
96
|
+
<
|
|
97
|
+
const ParamList extends ParamListBase,
|
|
98
|
+
const NavigatorID extends string | undefined = string | undefined,
|
|
99
|
+
>(): TypedNavigator<
|
|
100
|
+
StandardNavigationTypeBagFor<TypeBag, ParamList, NavigatorID>,
|
|
101
|
+
undefined
|
|
102
|
+
>;
|
|
103
|
+
<const Config extends StaticConfig<StandardNavigationDefaultBag<TypeBag>>>(
|
|
104
|
+
config: Config & StaticConfig<StandardNavigationDefaultBag<TypeBag>>
|
|
105
|
+
): TypedNavigator<
|
|
106
|
+
StandardNavigationTypeBagFor<
|
|
107
|
+
TypeBag,
|
|
108
|
+
StaticParamList<{ config: Config }> & ParamListBase,
|
|
109
|
+
string | undefined
|
|
110
|
+
>,
|
|
111
|
+
Config
|
|
112
|
+
>;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export interface StandardNavigationTypeBagBase extends NavigatorTypeBagBase {
|
|
116
|
+
ActionHelpers: {};
|
|
117
|
+
ScreenOptions: {};
|
|
118
|
+
EventMap: EventMapBase;
|
|
119
|
+
RouterOptions: DefaultRouterOptions;
|
|
120
|
+
NavigationList: {
|
|
121
|
+
[RouteName in keyof this['ParamList']]: NavigationProp<
|
|
122
|
+
this['ParamList'],
|
|
123
|
+
RouteName,
|
|
124
|
+
this['NavigatorID'],
|
|
125
|
+
this['State'],
|
|
126
|
+
this['ScreenOptions'],
|
|
127
|
+
this['EventMap']
|
|
128
|
+
> &
|
|
129
|
+
ActionHelpersOf<this['ActionHelpers']>;
|
|
130
|
+
};
|
|
131
|
+
Navigator: React.ComponentType<{}>;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function createStandardNavigationFactories<
|
|
135
|
+
TypeBag extends StandardNavigationTypeBagBase,
|
|
136
|
+
NavigatorProps extends object = {},
|
|
137
|
+
>(
|
|
138
|
+
navigator: ReturnType<
|
|
139
|
+
typeof createStandardNavigator<
|
|
140
|
+
TypeBag['ScreenOptions'],
|
|
141
|
+
StandardEventMap<TypeBag['EventMap']>,
|
|
142
|
+
NavigatorProps
|
|
143
|
+
>
|
|
144
|
+
>,
|
|
145
|
+
router: RouterFactory<
|
|
146
|
+
StandardNavigationTypeBagFor<TypeBag, ParamListBase>['State'],
|
|
147
|
+
NavigationAction,
|
|
148
|
+
TypeBag['RouterOptions']
|
|
149
|
+
>,
|
|
150
|
+
mapper?: StandardNavigationPropsMapper<TypeBag, NavigatorProps>
|
|
151
|
+
): StandardNavigationFactories<TypeBag> {
|
|
152
|
+
const { type, version, NavigatorContent } = navigator;
|
|
153
|
+
|
|
154
|
+
if (type !== 'standard') {
|
|
155
|
+
throw new Error(
|
|
156
|
+
`createStandardNavigationFactories only works with standard navigator objects, but got navigator of ${typeof type === 'string' ? `type "${type}".` : 'unknown type.'}`
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (version !== 1) {
|
|
161
|
+
throw new Error(
|
|
162
|
+
`createStandardNavigationFactories only works with version 1 of standard navigator objects, but got version ${version}.`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
type Bag = StandardNavigationTypeBagFor<TypeBag, ParamListBase>;
|
|
167
|
+
type StandardArgs = StandardNavigationArgs<
|
|
168
|
+
TypeBag['ScreenOptions'],
|
|
169
|
+
StandardEventMap<TypeBag['EventMap']>
|
|
170
|
+
>;
|
|
171
|
+
|
|
172
|
+
function StandardNavigationNavigator(
|
|
173
|
+
props: StandardNavigationNavigatorProps<TypeBag>
|
|
174
|
+
) {
|
|
175
|
+
const builder = useNavigationBuilder<
|
|
176
|
+
Bag['State'],
|
|
177
|
+
TypeBag['RouterOptions'],
|
|
178
|
+
ActionHelpersOf<Bag['ActionHelpers']>,
|
|
179
|
+
TypeBag['ScreenOptions'],
|
|
180
|
+
TypeBag['EventMap']
|
|
181
|
+
>(router, props);
|
|
182
|
+
|
|
183
|
+
const buildHref = useBuildHref();
|
|
184
|
+
|
|
185
|
+
const routes = useMemoArray(
|
|
186
|
+
('preloadedRoutes' in builder.state &&
|
|
187
|
+
Array.isArray(builder.state.preloadedRoutes)
|
|
188
|
+
? builder.state.routes.concat(builder.state.preloadedRoutes)
|
|
189
|
+
: builder.state.routes
|
|
190
|
+
).map((route) => {
|
|
191
|
+
const href = buildHref(route.name, route.params);
|
|
192
|
+
|
|
193
|
+
return [
|
|
194
|
+
{
|
|
195
|
+
key: route.key,
|
|
196
|
+
name: route.name,
|
|
197
|
+
params: route.params,
|
|
198
|
+
href,
|
|
199
|
+
},
|
|
200
|
+
[route.key, route.name, route.params, href],
|
|
201
|
+
];
|
|
202
|
+
})
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
const state = React.useMemo(
|
|
206
|
+
(): StandardArgs['state'] => ({
|
|
207
|
+
index: builder.state.index,
|
|
208
|
+
routes,
|
|
209
|
+
}),
|
|
210
|
+
[builder.state.index, routes]
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
const descriptors: StandardArgs['descriptors'] = {};
|
|
214
|
+
|
|
215
|
+
for (const route of state.routes) {
|
|
216
|
+
const descriptor =
|
|
217
|
+
builder.descriptors[route.key] ?? builder.describe(route, true);
|
|
218
|
+
|
|
219
|
+
descriptors[route.key] = {
|
|
220
|
+
options: descriptor.options,
|
|
221
|
+
render: descriptor.render,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const actions = React.useMemo<StandardArgs['actions']>(
|
|
226
|
+
() => ({
|
|
227
|
+
navigate(name, params) {
|
|
228
|
+
builder.navigation.dispatch({
|
|
229
|
+
...CommonActions.navigate(name, params),
|
|
230
|
+
target: builder.state.key,
|
|
231
|
+
});
|
|
232
|
+
},
|
|
233
|
+
back() {
|
|
234
|
+
builder.navigation.goBack();
|
|
235
|
+
},
|
|
236
|
+
}),
|
|
237
|
+
[builder.navigation, builder.state.key]
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
const emitter = React.useMemo<StandardArgs['emitter']>(
|
|
241
|
+
() => ({
|
|
242
|
+
// @ts-expect-error - they are compatible
|
|
243
|
+
emit: builder.navigation.emit,
|
|
244
|
+
}),
|
|
245
|
+
[builder.navigation]
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
const mapped = mapper?.({
|
|
249
|
+
state: builder.state,
|
|
250
|
+
navigation: builder.navigation as StandardNavigation<TypeBag>,
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
// Omit props used by useNavigationBuilder and routers internally
|
|
254
|
+
const {
|
|
255
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
256
|
+
children,
|
|
257
|
+
id,
|
|
258
|
+
initialRouteName,
|
|
259
|
+
layout,
|
|
260
|
+
screenLayout,
|
|
261
|
+
screenListeners,
|
|
262
|
+
screenOptions,
|
|
263
|
+
UNSTABLE_routeNamesChangeBehavior,
|
|
264
|
+
UNSTABLE_router,
|
|
265
|
+
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
266
|
+
...rest
|
|
267
|
+
} = props;
|
|
268
|
+
|
|
269
|
+
return (
|
|
270
|
+
<builder.NavigationContent>
|
|
271
|
+
<NavigatorContent
|
|
272
|
+
{...(rest as NavigatorProps)}
|
|
273
|
+
{...mapped}
|
|
274
|
+
state={state}
|
|
275
|
+
descriptors={descriptors}
|
|
276
|
+
actions={actions}
|
|
277
|
+
emitter={emitter}
|
|
278
|
+
/>
|
|
279
|
+
</builder.NavigationContent>
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const createNavigator = createNavigatorFactory(
|
|
284
|
+
StandardNavigationNavigator
|
|
285
|
+
) as StandardNavigationCreateNavigator<TypeBag>;
|
|
286
|
+
|
|
287
|
+
const createScreen =
|
|
288
|
+
createScreenFactory<StandardNavigationDefaultBag<TypeBag>>();
|
|
289
|
+
|
|
290
|
+
return {
|
|
291
|
+
createNavigator,
|
|
292
|
+
createScreen,
|
|
293
|
+
};
|
|
294
|
+
}
|
package/src/index.tsx
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
export {
|
|
2
|
+
createStandardNavigationFactories,
|
|
3
|
+
type StandardNavigationCreateNavigator,
|
|
4
|
+
type StandardNavigationTypeBagBase,
|
|
5
|
+
} from './createStandardNavigationFactories';
|
|
1
6
|
export { createStaticNavigation } from './createStaticNavigation';
|
|
2
7
|
export { Link } from './Link';
|
|
3
8
|
export { LinkingContext } from './LinkingContext';
|
|
@@ -55,8 +55,7 @@ export function useLinking(
|
|
|
55
55
|
},
|
|
56
56
|
getStateFromPath = getStateFromPathDefault,
|
|
57
57
|
getActionFromState = getActionFromStateDefault,
|
|
58
|
-
}: Options
|
|
59
|
-
onUnhandledLinking: (lastUnhandledLining: string | undefined) => void
|
|
58
|
+
}: Options
|
|
60
59
|
) {
|
|
61
60
|
const independent = useNavigationIndependentTree();
|
|
62
61
|
|
|
@@ -69,28 +68,40 @@ export function useLinking(
|
|
|
69
68
|
return undefined;
|
|
70
69
|
}
|
|
71
70
|
|
|
72
|
-
if (enabled !== false && linkingHandlers.length) {
|
|
73
|
-
console.error(
|
|
74
|
-
[
|
|
75
|
-
'Looks like you have configured linking in multiple places. This is likely an error since deep links should only be handled in one place to avoid conflicts. Make sure that:',
|
|
76
|
-
"- You don't have multiple NavigationContainers in the app each with 'linking' enabled",
|
|
77
|
-
'- Only a single instance of the root component is rendered',
|
|
78
|
-
Platform.OS === 'android'
|
|
79
|
-
? "- You have set 'android:launchMode=singleTask' in the '<activity />' section of the 'AndroidManifest.xml' file to avoid launching multiple instances"
|
|
80
|
-
: '',
|
|
81
|
-
]
|
|
82
|
-
.join('\n')
|
|
83
|
-
.trim()
|
|
84
|
-
);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
71
|
const handler = Symbol();
|
|
88
72
|
|
|
89
73
|
if (enabled !== false) {
|
|
90
74
|
linkingHandlers.push(handler);
|
|
91
75
|
}
|
|
92
76
|
|
|
77
|
+
// In some cases, the effect cleanup may get called out of order
|
|
78
|
+
// This may result in multiple linking handlers being registered
|
|
79
|
+
// For example, when changing the wallpaper on Android
|
|
80
|
+
// Showing the error in a delay avoids false positives
|
|
81
|
+
const timer = setTimeout(() => {
|
|
82
|
+
if (
|
|
83
|
+
enabled !== false &&
|
|
84
|
+
linkingHandlers.length &&
|
|
85
|
+
!(linkingHandlers.length === 1 && linkingHandlers.includes(handler))
|
|
86
|
+
) {
|
|
87
|
+
console.error(
|
|
88
|
+
[
|
|
89
|
+
'Looks like you have configured linking in multiple places. This is likely an error since deep links should only be handled in one place to avoid conflicts. Make sure that:',
|
|
90
|
+
"- You don't have multiple NavigationContainers in the app each with 'linking' enabled",
|
|
91
|
+
'- Only a single instance of the root component is rendered',
|
|
92
|
+
Platform.OS === 'android'
|
|
93
|
+
? "- You have set 'android:launchMode=singleTask' in the '<activity />' section of the 'AndroidManifest.xml' file to avoid launching multiple instances"
|
|
94
|
+
: '',
|
|
95
|
+
]
|
|
96
|
+
.join('\n')
|
|
97
|
+
.trim()
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
}, 1000);
|
|
101
|
+
|
|
93
102
|
return () => {
|
|
103
|
+
clearTimeout(timer);
|
|
104
|
+
|
|
94
105
|
const index = linkingHandlers.indexOf(handler);
|
|
95
106
|
|
|
96
107
|
if (index > -1) {
|
|
@@ -152,15 +163,8 @@ export function useLinking(
|
|
|
152
163
|
return url.then((url) => {
|
|
153
164
|
const state = getStateFromURL(url);
|
|
154
165
|
|
|
155
|
-
if (typeof url === 'string') {
|
|
156
|
-
// If the link were handled, it gets cleared in NavigationContainer
|
|
157
|
-
onUnhandledLinking(extractPathFromURL(prefixes, url));
|
|
158
|
-
}
|
|
159
|
-
|
|
160
166
|
return state;
|
|
161
167
|
});
|
|
162
|
-
} else {
|
|
163
|
-
onUnhandledLinking(extractPathFromURL(prefixes, url));
|
|
164
168
|
}
|
|
165
169
|
}
|
|
166
170
|
|
|
@@ -177,7 +181,7 @@ export function useLinking(
|
|
|
177
181
|
};
|
|
178
182
|
|
|
179
183
|
return thenable as PromiseLike<ResultState | undefined>;
|
|
180
|
-
}, [getStateFromURL
|
|
184
|
+
}, [getStateFromURL]);
|
|
181
185
|
|
|
182
186
|
React.useEffect(() => {
|
|
183
187
|
const listener = (url: string) => {
|
|
@@ -189,9 +193,6 @@ export function useLinking(
|
|
|
189
193
|
const state = navigation ? getStateFromURL(url) : undefined;
|
|
190
194
|
|
|
191
195
|
if (navigation && state) {
|
|
192
|
-
// If the link were handled, it gets cleared in NavigationContainer
|
|
193
|
-
onUnhandledLinking(extractPathFromURL(prefixes, url));
|
|
194
|
-
|
|
195
196
|
const action = getActionFromStateRef.current(state, configRef.current);
|
|
196
197
|
|
|
197
198
|
if (action !== undefined) {
|
|
@@ -215,7 +216,7 @@ export function useLinking(
|
|
|
215
216
|
};
|
|
216
217
|
|
|
217
218
|
return subscribe(listener);
|
|
218
|
-
}, [enabled, getStateFromURL,
|
|
219
|
+
}, [enabled, getStateFromURL, ref, subscribe]);
|
|
219
220
|
|
|
220
221
|
return {
|
|
221
222
|
getInitialState,
|
package/src/useLinking.tsx
CHANGED
|
@@ -110,8 +110,7 @@ export function useLinking(
|
|
|
110
110
|
getStateFromPath = getStateFromPathDefault,
|
|
111
111
|
getPathFromState = getPathFromStateDefault,
|
|
112
112
|
getActionFromState = getActionFromStateDefault,
|
|
113
|
-
}: Options
|
|
114
|
-
onUnhandledLinking: (lastUnhandledLining: string | undefined) => void
|
|
113
|
+
}: Options
|
|
115
114
|
) {
|
|
116
115
|
const independent = useNavigationIndependentTree();
|
|
117
116
|
|
|
@@ -202,9 +201,6 @@ export function useLinking(
|
|
|
202
201
|
value = undefined;
|
|
203
202
|
}
|
|
204
203
|
}
|
|
205
|
-
|
|
206
|
-
// If the link were handled, it gets cleared in NavigationContainer
|
|
207
|
-
onUnhandledLinking(path);
|
|
208
204
|
}
|
|
209
205
|
|
|
210
206
|
const thenable = {
|
|
@@ -287,8 +283,6 @@ export function useLinking(
|
|
|
287
283
|
// We should only dispatch an action when going forward
|
|
288
284
|
// Otherwise the action will likely add items to history, which would mess things up
|
|
289
285
|
if (state) {
|
|
290
|
-
// If the link were handled, it gets cleared in NavigationContainer
|
|
291
|
-
onUnhandledLinking(path);
|
|
292
286
|
// Make sure that the routes in the state exist in the root navigator
|
|
293
287
|
// Otherwise there's an error in the linking configuration
|
|
294
288
|
if (validateRoutesNotExistInRootState(state)) {
|
|
@@ -326,13 +320,7 @@ export function useLinking(
|
|
|
326
320
|
navigation.resetRoot(state);
|
|
327
321
|
}
|
|
328
322
|
});
|
|
329
|
-
}, [
|
|
330
|
-
enabled,
|
|
331
|
-
history,
|
|
332
|
-
onUnhandledLinking,
|
|
333
|
-
ref,
|
|
334
|
-
validateRoutesNotExistInRootState,
|
|
335
|
-
]);
|
|
323
|
+
}, [enabled, history, ref, validateRoutesNotExistInRootState]);
|
|
336
324
|
|
|
337
325
|
React.useEffect(() => {
|
|
338
326
|
if (!enabled) {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
export function useMemoArray<T>(
|
|
4
|
+
entries: [item: T, deps: readonly unknown[]][]
|
|
5
|
+
): T[] {
|
|
6
|
+
const previousRef = React.useRef<
|
|
7
|
+
| {
|
|
8
|
+
entries: { item: T; deps: readonly unknown[] }[];
|
|
9
|
+
items: T[];
|
|
10
|
+
}
|
|
11
|
+
| undefined
|
|
12
|
+
>(undefined);
|
|
13
|
+
|
|
14
|
+
const previous = previousRef.current;
|
|
15
|
+
const next = entries.map(([item, deps], index) => {
|
|
16
|
+
const previousEntry = previous?.entries[index];
|
|
17
|
+
const depsEqual =
|
|
18
|
+
previousEntry &&
|
|
19
|
+
previousEntry.deps.length === deps.length &&
|
|
20
|
+
previousEntry.deps.every((it, index) => Object.is(it, deps[index]));
|
|
21
|
+
|
|
22
|
+
return depsEqual ? previousEntry : { item, deps };
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
if (
|
|
26
|
+
previous &&
|
|
27
|
+
previous.entries.length === next.length &&
|
|
28
|
+
next.every((entry, index) => entry === previous.entries[index])
|
|
29
|
+
) {
|
|
30
|
+
return previous.items;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const items = next.map((entry) => entry.item);
|
|
34
|
+
|
|
35
|
+
previousRef.current = {
|
|
36
|
+
entries: next,
|
|
37
|
+
items,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
return items;
|
|
41
|
+
}
|