【问题标题】:React router v4 redirect when no match不匹配时反应路由器 v4 重定向
【发布时间】:2018-10-24 18:00:59
【问题描述】:

我是 react-router(以及一般的客户端路由)的新手,所以我可能认为这一切都错了。如果是这种情况,请提前道歉......

基本上只想实现3个简单的规则:

  • 如果没有用户,重定向到'/login'
  • 否则,如果路由不存在,则重定向到“/”(根目录)
  • 否则让用户转到请求的路线

我在this.state.user 中跟踪用户。我当前的路由器似乎遵循前 2 条规则,但只让经过身份验证的用户看到主页('/profile' 重定向到 '/'),所以我知道我做错了什么,但不知道是什么。

 <Router>
    {this.state.user ? (
      <Switch>
        <Route path="/" exact component={Home}/>
        <Route path="/profile" exact component={Profile}/>
        <Route render={() => (<Redirect to="/" />)}/>
      </Switch>
    ) : (
      <Switch>
        <Route path="/login" exact component={Login}/>
        <Route render={() => (<Redirect to="/login" />)}/>
      </Switch>
    )}
 </Router>

感谢任何建议。谢谢

【问题讨论】:

  • 如果找不到路由,您可以简单地尝试 重定向到根(即 Home)组件吗?
  • 我在代码沙箱中尝试了相同的代码,并按预期访问了 /profile。请检查链接codesandbox.io/s/n422y545pl
  • Switch中不需要添加Redirect组件。您必须在希望用户登录的每个组件中设置条件渲染,即您检查用户是否已登录以查看路线,如果没有。然后渲染 react-router-dom 提供的 Redirect 组件。
  • @RahilAhmad 感谢您提供的示例。让我意识到路由发生在用户状态设置之前。

标签: reactjs authentication routing react-router react-router-v4


【解决方案1】:

对于任何到达这里的人,如果没有任何路线匹配,则寻找如何重定向:

<Switch>
  // ... your routes
  <Route render={() => <Redirect to="/" />} />
</Switch>

请注意,路由必须是 &lt;Switch&gt; 的直接子级,例如这不起作用:

<Switch>
  <Fragment>
    // ... your routes
    <Route render={() => <Redirect to="/" />} />
  </Fragment>
</Switch>

(可能在更新版本的 react-router 中已修复)

【讨论】:

  • 对我不起作用。 React 路由器 4.3.1,路由嵌套在 Switch 中。
  • @VonAxt 把它放在开关的最后。
  • 这很有效,感谢您澄清直接孩子的事情。
  • 为我工作! &lt;Router&gt; {loggedIn &amp;&amp; ( &lt;Switch&gt; &lt;Route path="/" exact component={StoryListPage}/&gt; &lt;Route path="/new-story" exact component={StoryEditorPage}/&gt; &lt;Redirect to={'/'}/&gt; &lt;/Switch&gt; )} {!loggedIn &amp;&amp; ( &lt;Switch&gt; &lt;Route path="/login"&gt; &lt;LoginPage/&gt; &lt;/Route&gt; &lt;Redirect to={'/login'}/&gt; &lt;/Switch&gt; )} &lt;/Router&gt;
【解决方案2】:

答案很简单

<Switch>
  <Route path="/login" exact component={Login}/>
  {!this.state.user && <Redirect to='/login' />}
  <Route path="/" exact component={Home}/>
  <Route path="/profile" exact component={Profile}/>
  <Redirect to="/" />
</Switch>

交换机和路由器的主要区别在于路由器会尝试执行所有匹配的路径并将内容附加在一起,交换机将在第一次匹配时停止。

我的应用程序有类似的方法,但我将受保护的路由包装在一个单独的文件中,然后将用户配置文件包装为 HOC

export const App = () => (
  <Switch>
    <Route exact path='/login' component={Login} />
    {!hasToken() && <Redirect to='/login' />}
    <Route path='/' component={ProtectedRoute} />
  </Switch>
)

protectedRoute.js

const ProtectedRoute = ({ userInfo }: Props) => (
  <Layout userInfo={userInfo}>
    <Switch>
      <Route exact path='/a' component={A} />
      <Route exact path='/b' component={B} />
      <Route path='/c' component={C} />
      <Redirect to='/a' />
    </Switch>
  </Layout>
)

export default withUserInfo(ProtectedRoute)

【讨论】:

  • "交换机和路由器的主要区别在于路由器会尝试执行所有匹配的路径并将内容附加在一起,交换机将在第一次匹配时停止。"这句话帮助我避免了无数小时的头发拉扯。
【解决方案3】:

您是否考虑过使用Route 包装器在Route 需要用户时检查用户?

const CanHasRouteAccess = ({ component: Component, iHasUser, ...rest }) => {
  return iHasUser ? (
    <Route {...rest} render={props => <Component {...props} />} />
  ) : (
    <Redirect to="/" />
  );
};

当没有用户时,您可以将 props 传递给 Route 或重定向到主页。

<CanHasRouteAccess
  path="/personal-data"
  exact
  component={Profile}
  iHasUser={Boolean(user)}
  />

【讨论】:

  • 感谢瑞恩,这是有道理且有效的。知道如何使用重定向到“/”来最好地处理没有匹配路由的情况吗?
  • @Egor 如果您在Switch 的底部使用没有路径的Route,它将捕获所有不匹配的路线。例如,&lt;Route component={NoMatch}/&gt;。 Source
猜你喜欢
  • 2018-02-06
  • 2017-08-10
  • 2019-06-22
  • 1970-01-01
  • 2019-05-23
  • 1970-01-01
  • 1970-01-01
  • 2021-09-29
  • 2020-10-22
相关资源
最近更新 更多