1 | import { AppDataContext } from '@optimistdigital/create-frontend/universal-react';
|
2 | import { BrowserRouter } from 'react-router-dom';
|
3 | import { StaticRouter, withRouter, matchPath } from 'react-router';
|
4 | import React from 'react';
|
5 |
|
6 | function usePrevious(value) {
|
7 | const ref = React.useRef();
|
8 | React.useEffect(() => {
|
9 | ref.current = value;
|
10 | });
|
11 | return ref.current;
|
12 | }
|
13 |
|
14 | const RouteChangeListener = withRouter(({ children, location, onChange }) => {
|
15 | const prevLocation = usePrevious(location);
|
16 |
|
17 | React.useEffect(() => {
|
18 | if (
|
19 | !prevLocation ||
|
20 | `${location.pathname}${location.search}` !== `${prevLocation.pathname}${prevLocation.search}`
|
21 | ) {
|
22 | onChange && onChange(location);
|
23 | }
|
24 |
|
25 | }, [location, onChange]);
|
26 | return children;
|
27 | });
|
28 |
|
29 | export default function Router({ children, ...passthrough }) {
|
30 | const appData = React.useContext(AppDataContext);
|
31 |
|
32 | if (__TARGET__ === 'web') {
|
33 | return (
|
34 | <BrowserRouter {...passthrough}>
|
35 | <RouteChangeListener children={children} onChange={appData.onRouteChange} />
|
36 | </BrowserRouter>
|
37 | );
|
38 | }
|
39 |
|
40 | |
41 |
|
42 |
|
43 | return (
|
44 | <StaticRouter {...passthrough} location={appData.url} context={appData.serverContext}>
|
45 | {children}
|
46 | </StaticRouter>
|
47 | );
|
48 | }
|
49 |
|
50 | export async function getRouteData(location, routes, backendData) {
|
51 | const route = routes.find(x => matchPath(location.pathname, { exact: true, ...x }));
|
52 |
|
53 | let updater;
|
54 | if (route && route.component && route.component.getPageData) {
|
55 | updater = await route.component.getPageData(location, matchPath(location.pathname, route).params, backendData);
|
56 | }
|
57 |
|
58 | return updater || (prevState => prevState);
|
59 | }
|