|
1 | 1 | import React, { useRef } from 'react';
|
2 | 2 |
|
3 |
| -import { createMemoryHistory, MemoryHistoryBuildOptions } from 'history'; |
| 3 | +import { createMemoryHistory } from 'history'; |
4 | 4 |
|
5 | 5 | import { Router } from '../router';
|
6 |
| -import { RouterProps } from '../router/types'; |
7 | 6 |
|
8 | 7 | import { MemoryRouterProps } from '../../common/types';
|
9 | 8 |
|
10 |
| -const getRouterProps = (memoryRouterProps: MemoryRouterProps) => { |
11 |
| - const { |
12 |
| - isStatic = false, |
13 |
| - isGlobal = true, |
14 |
| - basePath, |
15 |
| - routes, |
16 |
| - resourceData, |
17 |
| - resourceContext, |
18 |
| - } = memoryRouterProps; |
19 |
| - let routerProps: Partial<RouterProps> = { |
20 |
| - basePath, |
21 |
| - routes, |
22 |
| - isStatic, |
23 |
| - isGlobal, |
24 |
| - }; |
| 9 | +const lazy = <T extends any>(callback: () => T) => { |
| 10 | + let firstCall = true; |
| 11 | + let current: T | undefined = undefined; |
25 | 12 |
|
26 |
| - if (resourceData) { |
27 |
| - routerProps = { ...routerProps, resourceData }; |
28 |
| - } |
| 13 | + return () => { |
| 14 | + if (firstCall) { |
| 15 | + current = callback(); |
| 16 | + firstCall = false; |
| 17 | + } |
29 | 18 |
|
30 |
| - if (resourceContext) { |
31 |
| - routerProps = { ...routerProps, resourceContext }; |
32 |
| - } |
33 |
| - |
34 |
| - return routerProps; |
| 19 | + return current; |
| 20 | + }; |
35 | 21 | };
|
36 | 22 |
|
37 |
| -/** |
38 |
| - * Ensures the router store uses memory history. |
39 |
| - * |
40 |
| - */ |
41 |
| -export const MemoryRouter = (props: MemoryRouterProps) => { |
42 |
| - const { location, children } = props; |
43 |
| - |
44 |
| - const newGetHistory = () => |
| 23 | +const useMemoryHistory = (location: string | undefined) => { |
| 24 | + const newGetHistory = lazy(() => |
45 | 25 | createMemoryHistory({
|
46 | 26 | initialEntries: location !== undefined ? [location] : undefined,
|
47 |
| - }); |
| 27 | + }) |
| 28 | + ); |
48 | 29 |
|
49 |
| - const historyState = useRef({ |
| 30 | + const historyStateCandidate = { |
50 | 31 | getHistory: newGetHistory,
|
51 | 32 | location,
|
52 |
| - }); |
| 33 | + }; |
| 34 | + |
| 35 | + const historyState = useRef(historyStateCandidate); |
53 | 36 |
|
54 |
| - if (historyState.current.location !== location) { |
55 |
| - historyState.current.getHistory = newGetHistory; |
| 37 | + if (historyState.current.location !== historyStateCandidate.location) { |
| 38 | + historyState.current = historyStateCandidate; |
56 | 39 | }
|
57 | 40 |
|
58 |
| - const routerProps = getRouterProps(props); |
| 41 | + return historyState.current.getHistory(); |
| 42 | +}; |
| 43 | + |
| 44 | +/** |
| 45 | + * Ensures the router store uses memory history. |
| 46 | + * |
| 47 | + */ |
| 48 | +export const MemoryRouter = ({ |
| 49 | + isStatic = false, |
| 50 | + isGlobal = true, |
| 51 | + location, |
| 52 | + children, |
| 53 | + basePath, |
| 54 | + routes, |
| 55 | + resourceData, |
| 56 | + resourceContext, |
| 57 | +}: MemoryRouterProps) => { |
| 58 | + const history = useMemoryHistory(location); |
59 | 59 |
|
60 | 60 | return (
|
61 | 61 | // @ts-ignore suppress history will be overwritten warning
|
62 | 62 | <Router
|
63 |
| - history={historyState.current.getHistory()} |
64 |
| - {...(routerProps as RouterProps)} |
| 63 | + isStatic={isStatic} |
| 64 | + isGlobal={isGlobal} |
| 65 | + history={history} |
| 66 | + basePath={basePath} |
| 67 | + routes={routes} |
| 68 | + resourceData={resourceData} |
| 69 | + resourceContext={resourceContext} |
65 | 70 | >
|
66 | 71 | {children}
|
67 | 72 | </Router>
|
|
0 commit comments