Reactjs 中的简单条件路由

IT技术 reactjs react-router react-redux react-router-v4 react-router-dom
2021-04-11 02:09:33

如何实现条件路由,即当且仅当某些条件满足时,路由才会发生。例如,当且仅当用户输入正确的凭据时,登录才应该成功并且用户应该能够看到欢迎页面。

如果我们直接点击类似 的 URL localhost:8080/welcome,则不应导航到欢迎页面。欢迎页面只应在登录后显示。

如何实现这一目标,有人可以帮助我吗?

应用程序.js

import React, { Component } from 'react';
import Header from './Header';

class App extends Component{
  render(){
   return(
     <div>
       <Header />
     </div>
   );
  }
}
export default App;

头文件.js

import React, { Component } from 'react';
import {Link} from 'react-router-dom';
import Login from './Login';
import SignUp from './SignUp';

class Header extends Component{
render(){
  return(
    <div>
    <nav class="navbar navbar-default">
     <div class="container-fluid">
     <ul class="nav navbar-nav">
      <li><Link to={Login}>Login</Link></li>
      <li><Link to={Login}>SignUp</Link></li>
    </ul>
    </div>
    </nav>
   
    </div>
   );
 } 
}

export default Header;

AllRoutes.js

import React, { Component } from 'react';
import { Switch, Route } from 'react-router-dom';
import Login from './Login';
import SignUp from './SignUp';
import Welcome from './Welcome';

class AllRoutes extends Component{
 render(){
   return(
     <Switch> 
       <Route exact path="/login" component={Login} />
       <Route exact path="/signup" component={SignUp} />
       <Route exact path="/Welcome" component={Welcome} />
     </Switch>
   );
  }
 }
 export default AllRoutes;

欢迎.js

import React, { Component } from 'react'; 

class Welcome extends Component{
render(){
 return(
  <div>
   <h2>Welcome to MainPage..</h2>
  </div>
  );
 }
}
export default Welcome;
6个回答

为了帮助回答您的问题,我认为您可能还需要询问应该如何阻止该路线。查看上面的示例,您还没有一种机制可以帮助回答“我是否应该能够访问此页面”的问题。这可能来自state、redux 或其他一些确定用户是否已登录的方法。

由于react-router只是简单的 React(我最喜欢的部分之一!!),您拥有了所有可用的工具,您可以有条件地显示React 应用程序的任何部分。

以下是您如何实现这一目标的几个示例(绝不是详尽无遗的。要有创意!这完全取决于您的要求和您使用的工具)

class AllRoutes extends Component{
  render(){
    return(
      <Switch> 
        <Route exact path="/login" component={Login} />
        <Route exact path="/signup" component={SignUp} />
        { this.state.authenticated && 
          <Route exact path="/Welcome" component={Welcome} />
        }
      </Switch>
    );
  }
}

我最喜欢的方法之一是创建一个ProtectedRoute组件

class ProtectedRoute extends Component {
  render() {
    const { component: Component, ...props } = this.props

    return (
      <Route 
        {...props} 
        render={props => (
          this.state.authenticated ?
            <Component {...props} /> :
            <Redirect to='/login' />
        )} 
      />
    )
  }
}

class AllRoutes extends Component {
  render() {
    return (
      <Switch>
        <Route path='/login' component={Login} />
        <ProtectedRoute path='/welcome' component={Welcome} />
      </Switch>
    )
  }
}

虽然我没有包含任何关于如何state.authenticated设置的特定逻辑,但这可能来自任何地方(绝不需要来自state)。尽力回答“我如何确定用户是否通过身份验证”的问题,并使用该机制作为处理路由身份验证的手段。

@prawn 我遇到了同样的问题,但设法让它像这样pastebin.com/h1WGZLwC
2021-05-22 02:09:33
这是一个很好的方法
2021-05-25 02:09:33
受保护的路线接近真的很棒。很棒的工作。
2021-05-25 02:09:33
很棒,但是当我将它与功能组件一起使用时,authenticated 是假的,手动输入“/welcome”它会在重定向到“/login”之前呈现 Welcome。你能解释为什么会发生这种情况吗?
2021-05-27 02:09:33
很棒的方法。尽管我收到一条警告,说我正在尝试重定向到我当前所在的同一条路线,因为 render() 被多次调用。你有没有遇到过这种情况?
2021-06-13 02:09:33

为此,您需要将整个应用程序分成两部分,通常可访问的部分和受保护的部分。只有成功登录后才能访问受保护的部分。

要实现该功能,请创建受保护部分的包装器,并使用 定义其路由path='/',并将条件放入其中。所有受保护的路由都应在该包装器组件内定义。如果有人试图在没有登录的情况下访问这些路由,包装器会将他们重定向到登录页面。

像这样:

class AllRoutes extends Component{
 render(){
   return(
     <Switch> 
       <Route exact path="/login" component={Login} />
       <Route exact path="/signup" component={SignUp} />
       <Route path="/" component={AppWrapper} />
     </Switch>
   );
  }
 }

AppWrapper 组件(假设您正在使用某种方式来维护用户是否已登录,因此请正确检查 if 条件):

import { Redirect } from 'react-router-dom'

class AppWrapper extends Component{
  render(){

  if(/*not login*/)
    return <Redirect to="/login" />

   return(
     <div>
       App wrapper
       <Route path='/Welcome' component={Welcome} />
     </div>
   );
  }
}

我想通过简单的解决方案加入聚会。

只需在组件 prop 中进行条件渲染,如下所示:

<Router>
  <Navigation />
  <Switch>
      <Route
         exact
         path="/"
         component={
          loading
           ? () => <div>Loading posts...</div>
         : () => <Home posts={posts} />
        }
      />
    <Route path="/login" component={Login} />
  </Switch>
</Router>

在这里,我试图从 api 获取一些数据,当它获取(加载)应该是 false 并呈现 Home 组件时。

您可以执行以下操作:

 let redirectToUrl;
      if ( not logged in ) //check condition
      {
        redirectToUrl = <Redirect to={loginPage}/>;
      }

并使用相同的:

  <Router>
     <div>
      {redirectToUrl}
       <Switch>
       <Route />
        </switch>
       </div>
</Router>

同样,您需要从 react-router-dom 导入:

import {
  BrowserRouter as Router,
  Route,
  browserHistory,
  Redirect,
  Link,
  Switch
} from "react-router-dom";

最好的方法是创建一个 HOC。考虑到您正在 Redux 存储中维护身份验证状态。否则,您可以检查自己的变量。

创建 requireAuth.js

import React, { Component } from 'react';
import { connect } from 'react-redux';

export default function(ComposedComponent) {
  class Authentication extends Component {
    static contextTypes = {
      router: React.PropTypes.object
    }

    componentWillMount() {
      if (!this.props.authenticated) {
        this.context.router.push('/');
      }
    }

    componentWillUpdate(nextProps) {
      if (!nextProps.authenticated) {
        this.context.router.push('/');
      }
    }

    render() {
      return <ComposedComponent {...this.props} />
    }
  }

  function mapStateToProps(state) {
    return { authenticated: state.auth.authenticated };
  }

  return connect(mapStateToProps)(Authentication);
}

现在在路由中你可以使用这个 hoc 并传递组件。

import RequireAuth from './requireAuth';
...

<Route exact path="/Welcome" component={RequireAuth(Welcome)} />