forked from 4Catalyzer/found
-
Notifications
You must be signed in to change notification settings - Fork 0
/
createFarceRouter.tsx
57 lines (48 loc) · 1.63 KB
/
createFarceRouter.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import useIsomorphicEffect from '@restart/hooks/useIsomorphicEffect';
import React, { forwardRef, useImperativeHandle, useState } from 'react';
import createBaseRouter from './createBaseRouter';
import createFarceStore from './createFarceStore';
import { FarceRouter, FarceRouterOptions, FoundState } from './typeUtils';
export default function createFarceRouter({
store: userStore,
historyProtocol,
historyMiddlewares,
historyOptions,
routeConfig,
// @ts-ignore TODO: matcher options should not accessible to end user
matcherOptions,
getFound = ({ found }: any) => found as FoundState,
...options
}: FarceRouterOptions): FarceRouter {
const Router = createBaseRouter(options);
const store =
userStore ||
createFarceStore({
historyProtocol,
historyMiddlewares,
historyOptions,
routeConfig,
matcherOptions,
});
const FarceRouterInstance: FarceRouter = forwardRef((props, ref) => {
const [state, setState] = useState(() => {
const { match, resolvedMatch } = getFound(store.getState());
return { match, resolvedMatch };
});
useIsomorphicEffect(() => {
return store.subscribe(() => {
setState((prev) => {
const { match, resolvedMatch } = getFound(store.getState());
if (prev?.match === match && prev.resolvedMatch === resolvedMatch) {
return prev;
}
return { match, resolvedMatch };
});
});
}, []);
useImperativeHandle(ref, () => store, []);
return <Router {...props} {...state} store={store} />;
});
FarceRouterInstance.displayName = 'FarceRouter';
return FarceRouterInstance;
}