【问题标题】:React Router v4 global no match to nested route childsReact Router v4 全局与嵌套路由子节点不匹配
【发布时间】:2017-09-03 11:43:01
【问题描述】:

当我在 React Router V4 中有嵌套路由时,如何将用户重定向到 NoMatch 组件?

这是我的代码:

import React from 'react';
import ReactDOM from 'react-dom';
import injectTapEventPlugin from 'react-tap-event-plugin';
injectTapEventPlugin();

import {
    BrowserRouter as Router,
    Route,
    Switch
}
from 'react-router-dom';
import Website from './website/Website';

const Register = ({ match}) => {
    return (
        <div>
            <Route exact path={match.url} render={() => {return <h1>Register</h1>} } />
            <Route path={`${match.url}/detail`} render={()=>{return <h1>Register Detail</h1>}} />
        </div>
    )
}

const App = () => (
    <Router>
        <Switch>
                <Route exact path="/" render={() =>  {return <h1>Home</h1> }} />
                <Route path="/register" component={Register} />
                <Route component={() => {return <h1>Not found!</h1>}} />
        </Switch>
    </Router>
);

ReactDOM.render(
    <App/>, document.getElementById('root'));

如您所见,Register 下方有一个 NoMatch 路由,但我不想在我的子组件 Register 上使用相同的路由映射。这样,如果我去 /register/unregisteredmatch 页面只是显示空白,因为不要输入 NoMatch Route。

如何在不指定子路由的情况下映射全局 NoMatch?我不想将此责任传递给子组件。

谢谢。

【问题讨论】:

  • 您将需要创建 HoC,无论它内部是否有匹配的子路由,注册都会始终呈现。所以你需要为此创建一个处理程序
  • @ReiDien 如果我理解的话,我需要做的是创建一个封装 NoMatch 处理程序的“抽象”组件......我说的对吗?谢谢

标签: javascript reactjs nested-routes react-router-v4 no-match


【解决方案1】:

我对 Switch 有同样的问题,因为如果我不去 /a

,以下内容将始终呈现我的 NoMatch 组件
<Router history={history}>
  <Switch>
    <Route path='/a' component={A} />
    <Switch>
      <Route path='/b' component={B} />
      <Route path='/b/:id' component={C} />
    </Switch>
    <Route path="*" component={NoMatch}/>
  </Switch>
</Router>

但是,如果您像这样将 NoMatch 移动到嵌套的 Switch 内,它将按预期工作:

<Router history={history}>
  <Switch>
    <Route path='/a' component={A} />
    <Switch>
      <Route path='/b' component={B} />
      <Route path='/b/:id' component={C} />
      <Route path="*" component={NoMatch}/>  
    </Switch>
  </Switch>
</Router>

即使这是问题的“解决方案”,它也不是您想要的,因为第二个 Switch 与第一个 Route 一样位于不同的文件中.

因此,随着应用程序的增长和更多路由在不同文件中发挥作用,您永远不知道需要将 NoMatch 路由放在哪里才能使其按预期工作。

你有没有找到解决这个问题的其他方法?

【讨论】:

  • 嗨!我认为解决此问题的最佳方法是使用高阶组件来处理未找到的匹配项,正如@ReiDien 在上面的评论中所解释的那样。我还没试过。
  • 发现不支持嵌套Switch。因此,在不同文件中配置路由后,您不应从这些文件中返回 Switch。我所做的是返回一个包含 /b 和 /b/:id 路由的路由数组。
【解决方案2】:

您可以做的是在您的根应用程序中定义所有可能允许的路由。因此,使用可选模式调整您的 App 组件,如下所示:

const App = () => (
    <Router>
        <Switch>
                <Route exact path="/" render={() =>  {return <h1>Home</h1> }} />
                <Route path="/register/(detail)?" exact component={Register} />
                <Route component={() => {return <h1>Not found!</h1>}} />
        </Switch>
    </Router>
);

【讨论】:

  • 谢谢@Javaguru!我试图在没有在主文件中指定的情况下解耦我的组件。仅出于动态导入目的,并且因为我不想在主文件中映射我的路线。我知道我可以根据导入创建一个路由文件,但我正在寻找一种在我的模块上执行此操作的方法。
猜你喜欢
  • 1970-01-01
  • 2021-12-09
  • 2021-03-22
  • 2017-08-28
  • 2019-01-07
  • 2017-06-25
  • 2017-11-11
  • 1970-01-01
相关资源
最近更新 更多