@react-navigation/routers 8.0.0-alpha.5 → 8.0.0-alpha.7

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.
@@ -6,7 +6,6 @@ import { createRouteFromAction } from './createRouteFromAction';
6
6
  import type {
7
7
  CommonNavigationAction,
8
8
  DefaultRouterOptions,
9
- NavigationRoute,
10
9
  NavigationState,
11
10
  ParamListBase,
12
11
  Route,
@@ -46,6 +45,12 @@ export type StackActionType =
46
45
  };
47
46
  source?: string | undefined;
48
47
  target?: string | undefined;
48
+ }
49
+ | {
50
+ type: 'RETAIN';
51
+ payload: { enable: boolean };
52
+ source?: string | undefined;
53
+ target?: string | undefined;
49
54
  };
50
55
 
51
56
  export type StackRouterOptions = DefaultRouterOptions;
@@ -57,9 +62,11 @@ export type StackNavigationState<ParamList extends ParamListBase> =
57
62
  */
58
63
  type: 'stack';
59
64
  /**
60
- * List of routes, which are supposed to be preloaded before navigating to.
65
+ * List of route keys to retain in the stack.
66
+ * When a retained route gets removed from the stack,
67
+ * it'll be kept in routes and can be navigated to again.
61
68
  */
62
- preloadedRoutes: NavigationRoute<ParamList, keyof ParamList>[];
69
+ retainedRouteKeys: string[];
63
70
  };
64
71
 
65
72
  export type StackActionHelpers<ParamList extends ParamListBase> = {
@@ -124,6 +131,15 @@ export type StackActionHelpers<ParamList extends ParamListBase> = {
124
131
  ]
125
132
  : never
126
133
  ): void;
134
+
135
+ /**
136
+ * Enable or disable retaining the current route in the stack.
137
+ * When a retained route gets removed from the stack,
138
+ * it'll be kept in routes and can be navigated to again.
139
+ *
140
+ * @param enable Whether to retain the current route in the stack or not.
141
+ */
142
+ retain(enable: boolean): void;
127
143
  };
128
144
 
129
145
  export const StackActions = {
@@ -158,6 +174,103 @@ export const StackActions = {
158
174
  },
159
175
  } as const satisfies StackActionType;
160
176
  },
177
+ retain(enable: boolean) {
178
+ return {
179
+ type: 'RETAIN',
180
+ payload: { enable },
181
+ } as const satisfies StackActionType;
182
+ },
183
+ };
184
+
185
+ function retainRoutes<ParamList extends ParamListBase>(
186
+ previousState: StackNavigationState<ParamList>,
187
+ nextState: StackNavigationState<ParamList>
188
+ ) {
189
+ if (!nextState.retainedRouteKeys.length) {
190
+ return nextState;
191
+ }
192
+
193
+ const retainedRouteKeySet = new Set(nextState.retainedRouteKeys);
194
+ const nextRouteKeySet = new Set(nextState.routes.map((route) => route.key));
195
+ const retainedRoutes = getActiveRoutes(previousState).filter(
196
+ (route) =>
197
+ retainedRouteKeySet.has(route.key) && !nextRouteKeySet.has(route.key)
198
+ );
199
+
200
+ if (!retainedRoutes.length) {
201
+ return nextState;
202
+ }
203
+
204
+ const removedRetainedRouteKeys = new Set(
205
+ retainedRoutes.map((route) => route.key)
206
+ );
207
+
208
+ return getStateWithRoutes(
209
+ nextState,
210
+ getActiveRoutes(nextState),
211
+ getPreloadedRoutes(nextState),
212
+ retainedRoutes.concat(
213
+ getRetainedRoutes(nextState).filter(
214
+ (route) => !removedRetainedRouteKeys.has(route.key)
215
+ )
216
+ )
217
+ );
218
+ }
219
+
220
+ const getActiveRoutes = <ParamList extends ParamListBase>(
221
+ state: StackNavigationState<ParamList>
222
+ ) => state.routes.slice(0, state.index + 1);
223
+
224
+ const getInactiveRoutes = <ParamList extends ParamListBase>(
225
+ state: StackNavigationState<ParamList>
226
+ ) => state.routes.slice(state.index + 1);
227
+
228
+ const getPreloadedRoutes = <ParamList extends ParamListBase>(
229
+ state: StackNavigationState<ParamList>
230
+ ) => {
231
+ const retainedRouteKeySet = new Set(state.retainedRouteKeys);
232
+
233
+ return getInactiveRoutes(state).filter(
234
+ (route) => !retainedRouteKeySet.has(route.key)
235
+ );
236
+ };
237
+
238
+ const getRetainedRoutes = <ParamList extends ParamListBase>(
239
+ state: StackNavigationState<ParamList>
240
+ ) => {
241
+ const retainedRouteKeySet = new Set(state.retainedRouteKeys);
242
+
243
+ return getInactiveRoutes(state).filter((route) =>
244
+ retainedRouteKeySet.has(route.key)
245
+ );
246
+ };
247
+
248
+ const getStateWithRoutes = <ParamList extends ParamListBase>(
249
+ state: StackNavigationState<ParamList>,
250
+ activeRoutes: Route<string>[],
251
+ preloadedRoutes = getPreloadedRoutes(state),
252
+ retainedRoutes = getRetainedRoutes(state)
253
+ ) => {
254
+ const routeKeySet = new Set(activeRoutes.map((route) => route.key));
255
+ const retainedRouteKeySet = new Set(state.retainedRouteKeys);
256
+
257
+ const filteredRetainedRoutes = retainedRoutes.filter(
258
+ (route) => !routeKeySet.has(route.key)
259
+ );
260
+
261
+ const filteredPreloadedRoutes = preloadedRoutes.filter(
262
+ (route) =>
263
+ !retainedRouteKeySet.has(route.key) && !routeKeySet.has(route.key)
264
+ );
265
+
266
+ return {
267
+ ...state,
268
+ index: activeRoutes.length - 1,
269
+ routes: activeRoutes.concat(
270
+ filteredRetainedRoutes,
271
+ filteredPreloadedRoutes
272
+ ),
273
+ };
161
274
  };
162
275
 
163
276
  export function StackRouter(options: StackRouterOptions) {
@@ -182,7 +295,7 @@ export function StackRouter(options: StackRouterOptions) {
182
295
  key: `stack-${nanoid()}`,
183
296
  index: 0,
184
297
  routeNames,
185
- preloadedRoutes: [],
298
+ retainedRouteKeys: [],
186
299
  routes: [
187
300
  {
188
301
  key: `${initialRouteName}-${nanoid()}`,
@@ -214,24 +327,6 @@ export function StackRouter(options: StackRouterOptions) {
214
327
  : route.params,
215
328
  }));
216
329
 
217
- const preloadedRoutes =
218
- state.preloadedRoutes
219
- ?.filter((route) => routeNames.includes(route.name))
220
- .map(
221
- (route) =>
222
- ({
223
- ...route,
224
- key: route.key || `${route.name}-${nanoid()}`,
225
- params:
226
- routeParamList[route.name] !== undefined
227
- ? {
228
- ...routeParamList[route.name],
229
- ...route.params,
230
- }
231
- : route.params,
232
- }) as Route<string>
233
- ) ?? [];
234
-
235
330
  if (routes.length === 0) {
236
331
  const initialRouteName =
237
332
  options.initialRouteName !== undefined
@@ -245,14 +340,23 @@ export function StackRouter(options: StackRouterOptions) {
245
340
  });
246
341
  }
247
342
 
343
+ const index = Math.min(
344
+ Math.max(state.index ?? routes.length - 1, 0),
345
+ routes.length - 1
346
+ );
347
+
348
+ const routeKeys = new Set(routes.map((route) => route.key));
349
+ const retainedRouteKeys =
350
+ state.retainedRouteKeys?.filter((key) => routeKeys.has(key)) ?? [];
351
+
248
352
  return {
249
353
  stale: false,
250
354
  type: 'stack',
251
355
  key: `stack-${nanoid()}`,
252
- index: routes.length - 1,
356
+ index,
253
357
  routeNames,
254
358
  routes,
255
- preloadedRoutes,
359
+ retainedRouteKeys,
256
360
  };
257
361
  },
258
362
 
@@ -260,7 +364,19 @@ export function StackRouter(options: StackRouterOptions) {
260
364
  state,
261
365
  { routeNames, routeParamList, routeKeyChanges }
262
366
  ) {
263
- const routes = state.routes.filter(
367
+ const routes = getActiveRoutes(state).filter(
368
+ (route) =>
369
+ routeNames.includes(route.name) &&
370
+ !routeKeyChanges.includes(route.name)
371
+ );
372
+
373
+ const preloadedRoutes = getPreloadedRoutes(state).filter(
374
+ (route) =>
375
+ routeNames.includes(route.name) &&
376
+ !routeKeyChanges.includes(route.name)
377
+ );
378
+
379
+ const retainedRoutes = getRetainedRoutes(state).filter(
264
380
  (route) =>
265
381
  routeNames.includes(route.name) &&
266
382
  !routeKeyChanges.includes(route.name)
@@ -280,36 +396,54 @@ export function StackRouter(options: StackRouterOptions) {
280
396
  });
281
397
  }
282
398
 
283
- return {
284
- ...state,
285
- routeNames,
399
+ const routeKeys = new Set(
400
+ [...routes, ...preloadedRoutes, ...retainedRoutes].map(
401
+ (route) => route.key
402
+ )
403
+ );
404
+
405
+ const retainedRouteKeys = state.retainedRouteKeys.filter((key) =>
406
+ routeKeys.has(key)
407
+ );
408
+
409
+ return getStateWithRoutes(
410
+ {
411
+ ...state,
412
+ routeNames,
413
+ retainedRouteKeys,
414
+ },
286
415
  routes,
287
- index: Math.min(state.index, routes.length - 1),
288
- };
416
+ preloadedRoutes,
417
+ retainedRoutes
418
+ );
289
419
  },
290
420
 
291
421
  getStateForRouteFocus(state, key) {
292
- const index = state.routes.findIndex((r) => r.key === key);
422
+ const routes = getActiveRoutes(state);
423
+ const index = routes.findIndex((r) => r.key === key);
293
424
 
294
425
  if (index === -1 || index === state.index) {
295
426
  return state;
296
427
  }
297
428
 
298
- return {
299
- ...state,
300
- index,
301
- routes: state.routes.slice(0, index + 1),
302
- };
429
+ return retainRoutes(
430
+ state,
431
+ getStateWithRoutes(state, routes.slice(0, index + 1))
432
+ );
303
433
  },
304
434
 
305
435
  getStateForAction(state, action, options) {
306
436
  const { routeParamList } = options;
307
437
 
438
+ const routes = getActiveRoutes(state);
439
+ const preloadedRoutes = getPreloadedRoutes(state);
440
+ const inactiveRoutes = getInactiveRoutes(state);
441
+
308
442
  switch (action.type) {
309
443
  case 'REPLACE': {
310
444
  const currentIndex =
311
445
  action.target === state.key && action.source
312
- ? state.routes.findIndex((r) => r.key === action.source)
446
+ ? routes.findIndex((r) => r.key === action.source)
313
447
  : state.index;
314
448
 
315
449
  if (currentIndex === -1) {
@@ -323,8 +457,8 @@ export function StackRouter(options: StackRouterOptions) {
323
457
  const getId = options.routeGetIdList[action.payload.name];
324
458
  const id = getId?.({ params: action.payload.params });
325
459
 
326
- // Re-use preloaded route if available
327
- let route = state.preloadedRoutes.find(
460
+ // Re-use inactive route if available
461
+ let route = inactiveRoutes.find(
328
462
  (route) =>
329
463
  route.name === action.payload.name &&
330
464
  id === getId?.({ params: route.params })
@@ -334,15 +468,14 @@ export function StackRouter(options: StackRouterOptions) {
334
468
  route = createRouteFromAction({ action, routeParamList });
335
469
  }
336
470
 
337
- return {
338
- ...state,
339
- routes: state.routes.map((r, i) =>
340
- i === currentIndex ? route : r
341
- ),
342
- preloadedRoutes: state.preloadedRoutes.filter(
343
- (r) => r.key !== route.key
344
- ),
345
- };
471
+ return retainRoutes(
472
+ state,
473
+ getStateWithRoutes(
474
+ state,
475
+ routes.map((r, i) => (i === currentIndex ? route : r)),
476
+ preloadedRoutes.filter((r) => r.key !== route.key)
477
+ )
478
+ );
346
479
  }
347
480
 
348
481
  case 'PUSH':
@@ -357,7 +490,7 @@ export function StackRouter(options: StackRouterOptions) {
357
490
  let route: Route<string> | undefined;
358
491
 
359
492
  if (action.type === 'NAVIGATE') {
360
- const currentRoute = state.routes[state.index];
493
+ const currentRoute = routes[state.index];
361
494
 
362
495
  if (id !== undefined) {
363
496
  if (
@@ -366,8 +499,8 @@ export function StackRouter(options: StackRouterOptions) {
366
499
  ) {
367
500
  route = currentRoute;
368
501
  } else if (action.payload.pop) {
369
- for (let i = state.routes.length - 1; i >= 0; i--) {
370
- const r = state.routes[i];
502
+ for (let i = routes.length - 1; i >= 0; i--) {
503
+ const r = routes[i];
371
504
 
372
505
  if (r.name !== action.payload.name) {
373
506
  continue;
@@ -404,7 +537,7 @@ export function StackRouter(options: StackRouterOptions) {
404
537
  if (action.payload.name === currentRoute.name) {
405
538
  route = currentRoute;
406
539
  } else if (action.payload.pop) {
407
- route = state.routes.findLast(
540
+ route = routes.findLast(
408
541
  (route) => route.name === action.payload.name
409
542
  );
410
543
  }
@@ -412,7 +545,7 @@ export function StackRouter(options: StackRouterOptions) {
412
545
  }
413
546
 
414
547
  if (!route) {
415
- route = state.preloadedRoutes.find(
548
+ route = inactiveRoutes.find(
416
549
  (route) =>
417
550
  route.name === action.payload.name &&
418
551
  id === getId?.({ params: route.params })
@@ -435,16 +568,16 @@ export function StackRouter(options: StackRouterOptions) {
435
568
  params = createParamsFromAction({ action, routeParamList });
436
569
  }
437
570
 
438
- let routes: Route<string>[];
571
+ let nextRoutes: Route<string>[];
439
572
 
440
573
  if (route) {
441
574
  if (action.type === 'NAVIGATE' && action.payload.pop) {
442
- routes = [];
575
+ nextRoutes = [];
443
576
 
444
577
  // Get all routes until the matching one
445
- for (const r of state.routes) {
578
+ for (const r of routes) {
446
579
  if (r.key === route.key) {
447
- routes.push({
580
+ nextRoutes.push({
448
581
  ...route,
449
582
  path:
450
583
  action.payload.path !== undefined
@@ -455,11 +588,22 @@ export function StackRouter(options: StackRouterOptions) {
455
588
  break;
456
589
  }
457
590
 
458
- routes.push(r);
591
+ nextRoutes.push(r);
592
+ }
593
+
594
+ if (!nextRoutes.some((r) => r.key === route.key)) {
595
+ nextRoutes.push({
596
+ ...route,
597
+ path:
598
+ action.payload.path !== undefined
599
+ ? action.payload.path
600
+ : route.path,
601
+ params,
602
+ });
459
603
  }
460
604
  } else {
461
- routes = state.routes.filter((r) => r.key !== route.key);
462
- routes.push({
605
+ nextRoutes = routes.filter((r) => r.key !== route.key);
606
+ nextRoutes.push({
463
607
  ...route,
464
608
  path:
465
609
  action.type === 'NAVIGATE' &&
@@ -470,8 +614,8 @@ export function StackRouter(options: StackRouterOptions) {
470
614
  });
471
615
  }
472
616
  } else {
473
- routes = [
474
- ...state.routes,
617
+ nextRoutes = [
618
+ ...routes,
475
619
  {
476
620
  key: `${action.payload.name}-${nanoid()}`,
477
621
  name: action.payload.name,
@@ -482,23 +626,25 @@ export function StackRouter(options: StackRouterOptions) {
482
626
  ];
483
627
  }
484
628
 
485
- return {
486
- ...state,
487
- index: routes.length - 1,
488
- preloadedRoutes: state.preloadedRoutes.filter(
489
- (route) => routes[routes.length - 1].key !== route.key
490
- ),
491
- routes,
492
- };
629
+ return retainRoutes(
630
+ state,
631
+ getStateWithRoutes(
632
+ state,
633
+ nextRoutes,
634
+ preloadedRoutes.filter(
635
+ (route) => nextRoutes[nextRoutes.length - 1].key !== route.key
636
+ )
637
+ )
638
+ );
493
639
  }
494
640
 
495
641
  case 'POP': {
496
642
  let currentIndex =
497
643
  action.target === state.key && action.source
498
- ? state.routes.findIndex((r) => r.key === action.source)
644
+ ? routes.findIndex((r) => r.key === action.source)
499
645
  : state.index;
500
646
 
501
- let route = state.routes[currentIndex];
647
+ let route = routes[currentIndex];
502
648
 
503
649
  /**
504
650
  * When popping entries,
@@ -511,11 +657,11 @@ export function StackRouter(options: StackRouterOptions) {
511
657
  */
512
658
  if (route.history?.length || currentIndex > 0) {
513
659
  let count = action.payload.count;
514
- let routes = state.routes;
660
+ let nextRoutes = routes;
515
661
 
516
662
  while (count > 0 && (route.history?.length || currentIndex > 0)) {
517
663
  if (route.history?.length) {
518
- routes = [...routes];
664
+ nextRoutes = [...nextRoutes];
519
665
 
520
666
  const end = Math.min(count, route.history.length);
521
667
  const last = route.history.at(-end);
@@ -524,7 +670,7 @@ export function StackRouter(options: StackRouterOptions) {
524
670
 
525
671
  count = count - removed;
526
672
 
527
- routes[currentIndex] = {
673
+ nextRoutes[currentIndex] = {
528
674
  ...route,
529
675
  params: last?.type === 'params' ? last.params : route.params,
530
676
  history,
@@ -532,33 +678,29 @@ export function StackRouter(options: StackRouterOptions) {
532
678
  }
533
679
 
534
680
  if (currentIndex > 0 && count > 0) {
535
- const length = routes.length;
681
+ const length = nextRoutes.length;
536
682
  const end = Math.max(currentIndex - count + 1, 1);
537
683
 
538
- routes = routes
684
+ nextRoutes = nextRoutes
539
685
  .slice(0, end)
540
- .concat(routes.slice(currentIndex + 1));
686
+ .concat(nextRoutes.slice(currentIndex + 1));
541
687
 
542
- const removed = length - routes.length;
688
+ const removed = length - nextRoutes.length;
543
689
 
544
690
  count = count - removed;
545
- currentIndex = routes.length - 1;
546
- route = routes[currentIndex];
691
+ currentIndex = nextRoutes.length - 1;
692
+ route = nextRoutes[currentIndex];
547
693
  }
548
694
  }
549
695
 
550
- return {
551
- ...state,
552
- index: routes.length - 1,
553
- routes,
554
- };
696
+ return retainRoutes(state, getStateWithRoutes(state, nextRoutes));
555
697
  }
556
698
 
557
699
  return null;
558
700
  }
559
701
 
560
702
  case 'POP_TO_TOP': {
561
- let route = state.routes[0];
703
+ let route = routes[0];
562
704
 
563
705
  if (state.index > 0 || route.history?.length) {
564
706
  if (route.history?.length) {
@@ -568,11 +710,7 @@ export function StackRouter(options: StackRouterOptions) {
568
710
  };
569
711
  }
570
712
 
571
- return {
572
- ...state,
573
- index: 0,
574
- routes: [route],
575
- };
713
+ return retainRoutes(state, getStateWithRoutes(state, [route]));
576
714
  }
577
715
 
578
716
  return null;
@@ -581,7 +719,7 @@ export function StackRouter(options: StackRouterOptions) {
581
719
  case 'POP_TO': {
582
720
  const currentIndex =
583
721
  action.target === state.key && action.source
584
- ? state.routes.findLastIndex((r) => r.key === action.source)
722
+ ? routes.findLastIndex((r) => r.key === action.source)
585
723
  : state.index;
586
724
 
587
725
  if (currentIndex === -1) {
@@ -601,7 +739,7 @@ export function StackRouter(options: StackRouterOptions) {
601
739
 
602
740
  if (id !== undefined) {
603
741
  for (let i = currentIndex; i >= 0; i--) {
604
- const r = state.routes[i];
742
+ const r = routes[i];
605
743
 
606
744
  if (r.name !== action.payload.name) {
607
745
  continue;
@@ -629,11 +767,11 @@ export function StackRouter(options: StackRouterOptions) {
629
767
  }
630
768
  }
631
769
  }
632
- } else if (state.routes[currentIndex].name === action.payload.name) {
770
+ } else if (routes[currentIndex].name === action.payload.name) {
633
771
  index = currentIndex;
634
772
  } else {
635
773
  for (let i = currentIndex; i >= 0; i--) {
636
- if (state.routes[i].name === action.payload.name) {
774
+ if (routes[i].name === action.payload.name) {
637
775
  index = i;
638
776
  break;
639
777
  }
@@ -642,8 +780,8 @@ export function StackRouter(options: StackRouterOptions) {
642
780
 
643
781
  // If the route doesn't exist, remove the current route and add the new one
644
782
  if (index === -1) {
645
- // Re-use preloaded route if available
646
- let route = state.preloadedRoutes.find(
783
+ // Re-use inactive route if available
784
+ let route = inactiveRoutes.find(
647
785
  (route) =>
648
786
  route.name === action.payload.name &&
649
787
  id === getId?.({ params: route.params })
@@ -653,19 +791,19 @@ export function StackRouter(options: StackRouterOptions) {
653
791
  route = createRouteFromAction({ action, routeParamList });
654
792
  }
655
793
 
656
- const routes = state.routes.slice(0, currentIndex).concat(route);
794
+ const nextRoutes = routes.slice(0, currentIndex).concat(route);
657
795
 
658
- return {
659
- ...state,
660
- index: routes.length - 1,
661
- routes,
662
- preloadedRoutes: state.preloadedRoutes.filter(
663
- (r) => r.key !== route.key
664
- ),
665
- };
796
+ return retainRoutes(
797
+ state,
798
+ getStateWithRoutes(
799
+ state,
800
+ nextRoutes,
801
+ preloadedRoutes.filter((r) => r.key !== route.key)
802
+ )
803
+ );
666
804
  }
667
805
 
668
- const route = state.routes[index];
806
+ const route = routes[index];
669
807
 
670
808
  let baseParams = route.params;
671
809
  let history = route.history;
@@ -691,20 +829,19 @@ export function StackRouter(options: StackRouterOptions) {
691
829
  params = createParamsFromAction({ action, routeParamList });
692
830
  }
693
831
 
694
- return {
695
- ...state,
696
- index,
697
- routes: [
698
- ...state.routes.slice(0, index),
832
+ return retainRoutes(
833
+ state,
834
+ getStateWithRoutes(state, [
835
+ ...routes.slice(0, index),
699
836
  params !== baseParams || historyIndex !== undefined
700
837
  ? { ...route, params, history }
701
- : state.routes[index],
702
- ],
703
- };
838
+ : routes[index],
839
+ ])
840
+ );
704
841
  }
705
842
 
706
843
  case 'GO_BACK':
707
- if (state.index > 0 || state.routes[state.index].history?.length) {
844
+ if (state.index > 0 || routes[state.index].history?.length) {
708
845
  return router.getStateForAction(
709
846
  state,
710
847
  {
@@ -719,6 +856,40 @@ export function StackRouter(options: StackRouterOptions) {
719
856
 
720
857
  return null;
721
858
 
859
+ case 'RETAIN': {
860
+ const routeKey = action.source ?? routes[state.index].key;
861
+
862
+ if (!state.routes.some((route) => route.key === routeKey)) {
863
+ return null;
864
+ }
865
+
866
+ if (action.payload.enable) {
867
+ if (state.retainedRouteKeys.includes(routeKey)) {
868
+ return state;
869
+ }
870
+
871
+ return {
872
+ ...state,
873
+ retainedRouteKeys: [...state.retainedRouteKeys, routeKey],
874
+ };
875
+ }
876
+
877
+ if (!state.retainedRouteKeys.includes(routeKey)) {
878
+ return state;
879
+ }
880
+
881
+ return getStateWithRoutes(
882
+ {
883
+ ...state,
884
+ retainedRouteKeys: state.retainedRouteKeys.filter(
885
+ (key) => key !== routeKey
886
+ ),
887
+ },
888
+ routes,
889
+ preloadedRoutes.filter((route) => route.key !== routeKey)
890
+ );
891
+ }
892
+
722
893
  case 'PRELOAD': {
723
894
  const getId = options.routeGetIdList[action.payload.name];
724
895
  const id = getId?.({ params: action.payload.params });
@@ -727,56 +898,59 @@ export function StackRouter(options: StackRouterOptions) {
727
898
  let route: Route<string> | undefined;
728
899
 
729
900
  if (action.payload.reuse) {
730
- route = state.preloadedRoutes.findLast(
901
+ route = preloadedRoutes.findLast(
731
902
  (route) =>
732
903
  route.name === action.payload.name &&
733
904
  (id === undefined || id === getId?.({ params: route.params }))
734
905
  );
735
906
 
736
907
  if (route) {
737
- return {
738
- ...state,
739
- preloadedRoutes: state.preloadedRoutes.map((r) =>
908
+ return getStateWithRoutes(
909
+ state,
910
+ routes,
911
+ preloadedRoutes.map((r) =>
740
912
  r.key === route?.key && r.params !== params
741
913
  ? { ...r, params }
742
914
  : r
743
- ),
744
- };
915
+ )
916
+ );
745
917
  }
746
918
  }
747
919
 
748
920
  if (id !== undefined) {
749
- route = state.routes.findLast(
921
+ route = routes.findLast(
750
922
  (route) =>
751
923
  route.name === action.payload.name &&
752
924
  id === getId?.({ params: route.params })
753
925
  );
754
926
  } else if (action.payload.reuse) {
755
- route = state.routes.findLast(
927
+ route = routes.findLast(
756
928
  (route) => route.name === action.payload.name
757
929
  );
758
930
  }
759
931
 
760
932
  if (route) {
761
- return {
762
- ...state,
763
- routes: state.routes.map((r) =>
933
+ return getStateWithRoutes(
934
+ state,
935
+ routes.map((r) =>
764
936
  r.key === route.key && r.params !== params
765
937
  ? { ...r, params }
766
938
  : r
767
939
  ),
768
- };
940
+ preloadedRoutes
941
+ );
769
942
  } else {
770
- return {
771
- ...state,
772
- preloadedRoutes: state.preloadedRoutes
943
+ return getStateWithRoutes(
944
+ state,
945
+ routes,
946
+ preloadedRoutes
773
947
  .filter(
774
948
  (r) =>
775
949
  r.name !== action.payload.name ||
776
950
  id !== getId?.({ params: r.params })
777
951
  )
778
- .concat(createRouteFromAction({ action, routeParamList })),
779
- };
952
+ .concat(createRouteFromAction({ action, routeParamList }))
953
+ );
780
954
  }
781
955
  }
782
956
 
@@ -785,10 +959,6 @@ export function StackRouter(options: StackRouterOptions) {
785
959
  }
786
960
  },
787
961
 
788
- getRoutesFromState(state) {
789
- return [...state.routes, ...state.preloadedRoutes];
790
- },
791
-
792
962
  actionCreators: StackActions,
793
963
  };
794
964