首页 > 解决方案 > 后退按钮后反应路由器“历史”和“位置”不匹配

问题描述

在我的 React 应用程序中,从 Home 导航到子页面然后点击后退按钮后,React<Router>在其内部状态中显示与其传递的道具不匹配的位置,并且地址栏中当前显示的 URL 显示history不正确<Route>

do的内容发生了<Route>变化;数据由位置更改 Redux 操作更新。显示<Route>显示新数据,但它是错误的<Route>

该应用程序的基本结构是:

<Root>                                  (custom)
  <Provider>                            (react-redux)
    <ConnectedRouter>                   (connected-react-router)
      <App>                             (custom)
        <Switch>                        (react-router-dom)
          <Route path="/" exact />      (react-router-dom)
          <Route path="/quality:q" />   (react-router-dom)

最初我们导航到根目录并<Route path="/>正确显示。我们点击一​​个链接,正确地把我们带到<Route path="/quality/:q" />. 从那里我们回击浏览器,URL 更改为/<Route path="/quality:q" />仍显示,但它不应该再显示了。

Redux devtools 显示了这个渲染树,我包含了一些我们明确使用的关键组件。

<Root>                                  (custom)
  <Provider>                            (react-redux)
    <ConnectedRouter>                   (connected-react-router)
      <Router>                          (injected)
        <Context.Provider>              (injected)
          <App>                             (custom)
            <Switch>                        (react-router-dom)
              <Route path="/" exact />      (react-router-dom)
              <Route path="/quality:q" />   (react-router-dom)

当处于这种不正确的状态时,一切<ConnectedRouter>都是正确的。<ConnectedRouter>有一个单一的道具,history它具有正确的位置,即根。

紧接其<Router>下方的是不匹配的。它有一个可以的history道具,但它的location状态陈旧,显示旧网址。

当错误的位置数据被上下文传递给<Route>s 时,他们会从他们的locationprop 中检查匹配的<Router>陈旧状态的路径。结果,<Route>呈现错误。

我无法弄清楚我做了什么导致这种不匹配。这都是简单的路线,并<Link>为从主页到子页面和返回的所有链接使用组件。

有没有人以前见过这个和/或可以指出我如何解决这个问题的方向?

不匹配的道具和状态截图

标签: reactjsreact-routerreact-router-reduxconnected-react-router

解决方案


我认为您的路由结构需要重构,因为您尝试匹配(可能是嵌套的)URL。

如果你想/quality/:id跌倒在地/,那么就Route需要成为一个孩子了component

例如,Route将是:

<Route path="/" component={Home} />

然后在Home组件内部,您将拥有Route使用match.url( route props ) 作为字符串匹配器的 child:

const Home = ({ match: { url } }) => (
 <>
  <div>Home<Home>
  <Switch>
    <Route path={`${url}quality/:q` component={Quality} />
    <Route path={`${url}some/other/route`} component={Example} />
  </Switch>
 </>
);

但是,如果您想要相反的情况, where/独立于/quality/:p,那么您需要使用exact

<Switch>
   <Route exact path="/" component={Home} />
   <Route exact path="/quality/:p" component={Quality} />
   <Route exact path="/some/other/route" component={Example} />
<Switch>

工作示例

在此示例中/home/about/dashboard是彼此独立的路由;但是,/dashboard是这些子路由的父级:/dashboard/settings并且/dashboard(顺序很重要!)并/dashboard呈现一个Dashboard组件,该组件也恰好是/dashboard/profile子路由的父级!顺序并且exact对于如何渲染每个嵌套路由很重要。我还在goBack里面包含了一个示例,pages/Profile以证明's 的历史记录与Route 历史记录路由connected-react-router保持一致。react-router-dom

演示

资源


如果您遵循上述约定,那么唯一的另一个问题react-hot-loader就是阻止状态更改。我个人不使用 RHL,因为我发现它相当有问题,但对每个人来说都是如此。也就是说,我connected-react-router在过去的 3 或 4 个项目中都使用过,而且我从来没有遇到过 props/state 不匹配的情况(除了一些共享的 redux 数据是陈旧的,需要在加载另一个正在重用的组件之前重置)相同的数据结构)。


推荐阅读