【问题标题】:React Router Link doesn't keep state in custom historyReact Router Link 不在自定义历史记录中保留状态
【发布时间】:2021-08-16 14:26:10
【问题描述】:

在我的项目中,我使用 React Router DOM 5.2.0。由于项目需要,我必须使用带有自定义历史记录的<Router />。事情是这样的:

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>

这是基本设置。 Page1Page2 是交叉链接组件,如下所示:

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;

这里的关键部分是Link 组件,它具有to 以对象为值的prop。在这个对象中我定义了state: { prevUrl: location.pathname },但是当我尝试在Page2 中访问它时,这个state 始终是null。这里有趣的是,如果我将&lt;Router /&gt; 更改为BrowserRouter 并从Switch 中删除自定义location - 一切都会很好,这意味着&lt;Link /&gt; 确实会传播状态。然而,就我而言,history 似乎根本没有处理状态。

系统:

  • Mac OS 11.4 Big Sur
  • 节点 12.16.2
  • NPM 6.14.11
  • 反应 16.13.1
  • react-router-dom 5.2.0

【问题讨论】:

  • 为什么不在useRouter 自定义挂钩中使用useLocation 挂钩?你为什么要在Switch 组件上使用不同的 位置?您可以毫无问题地将RoutercreateBrowserHistory history 对象一起使用,我认为这是Switch 上使用的奇怪location 对象为您搞砸了。
  • 似乎Switch 需要知道location 对象用于正确处理组件更新。如果我删除一个 - 它不会呈现新组件。在useRouter 中,我使用我创建的history 对象中的location 来提供给Router,这就是我不使用useLocation 的原因,因为它会从不同的对象返回我的位置。我创建了一个沙箱,以便更轻松地点击codesandbox.io/embed/…

标签: reactjs react-router react-router-dom history.js react-router-v5


【解决方案1】:

感谢https://stackoverflow.com/a/62583930/8080990这个帖子,我刚刚找到了答案

降级到history 版本 4,它可以完美运行!

Sandbox

【讨论】:

    猜你喜欢
    • 2016-07-05
    • 1970-01-01
    • 1970-01-01
    • 2015-05-23
    • 2018-05-14
    • 1970-01-01
    • 1970-01-01
    • 2017-08-17
    • 2017-12-08
    相关资源
    最近更新 更多