简体   繁体   中英

React Router Link doesn't keep state in custom history

In my project I use React Router DOM 5.2.0. I have to use <Router /> with custom history due to project needs. And this is how it goes:

Example on Sandbox

history.js

import { createBrowserHistory } from 'history';

const history = createBrowserHistory();

export default history;

useRouter.js

import {
  useParams,
  useRouteMatch,
} from 'react-router-dom';
import { useMemo } from 'react';

import history from './history';
import urlQueriesService from './urlQueriesService';

const useRouter = () => {
  const params = useParams();
  const match = useRouteMatch();
  const { location } = history;

  return useMemo(() => ({
    push: history.push,
    replace: history.replace,
    pathname: location?.pathname,

    query: {
      ...urlQueriesService.parse(location?.search),
      ...params,
    },

    match,
    location,
    history,
  }), [params, match, location, history]);
};

export default useRouter;

AppRoutes.jsx

import React from 'react';
import {
  Route,
  Switch,
} from 'react-router-dom';

import useRouter from './useRouter';
import TestPage from './TestPage';
import TestComponent from './TestComponent';

const AppRoutes = () => {
  const { location } = useRouter();
  return (
    <Switch location={location}>
      <Route exact path="/page-1" component={Page1} />
      <Route exact path="/page-2" component={Page2} />
    </Switch>
  );
};

export default AppRoutes;

App.jsx

import history from './history';

<Router history={history}>
  <AppRoutes />
</Router>

This is the basic setup. Page1 and Page2 are cross linking components and look like this:

import React from 'react';
import { Link } from 'react-router-dom';

import useRouter from './useRouter';

const Page1 = () => {
  const { location } = useRouter();

  return (
    <div>
      <h1>Test</h1>

      <div>
        <Link to={{ pathname: '/page-2', state: { prevUrl: location.pathname }}}>Stateful component</Link>
      </div>
    </div>
  );
};

export default Page1;

The key part here is Link component which has to prop with object as value. In this object I define state: { prevUrl: location.pathname } , but this state is always null when I try to access it in Page2 . The fun thing here is that if I change <Router /> to be BrowserRouter and remove custom location from Switch - things work very well, meaning <Link /> does propagate the state. In my case, however, it looks like state is not being handled by the history at all.

System:

  • Mac OS 11.4 Big Sur
  • Node 12.16.2
  • NPM 6.14.11
  • React 16.13.1
  • react-router-dom 5.2.0

I just found an answer thanks to this post https://stackoverflow.com/a/62583930/8080990

Downgrade to history version 4, and it works perfect!

Sandbox

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM