后退按钮后,反应路由器的历史记录和位置不匹配

问题描述 投票:2回答:1

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

<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>时,他们从location道具中获取了与<Router>的陈旧状态相匹配的路径。结果,将显示错误的<Route>

我不知道我做了什么导致这种不匹配。这都是简单的路线,并使用<Link>组件进行从首页到子页面再到子页面的所有链接。

以前有没有人看到过和/或可以指出我该如何解决此问题的方向?

Screenshot of mismatched props and state

reactjs react-router react-router-redux connected-react-router
1个回答
2
投票

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

如果您希望/quality/:id落在/之下,则Route必须是component的子级。

例如,Route为:

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

然后在Home组件内部,您将使用Routematch.url)作为字符串匹配器的子route props

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

但是,如果想要相反的情况,其中/独立于/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子路由的父级! Order和exact对于如何呈现每个嵌套路线很重要。我还在goBack中包含了一个pages/Profile示例,以证明connected-react-router的历史记录与react-router-dom路由历史记录路由保持一致。

demo

source


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

© www.soinside.com 2019 - 2024. All rights reserved.