使用react-router-dom

时间:2019-04-27 05:00:10

标签: reactjs react-router-dom

说明::

我正在使用reactJS应用,并使用react-router-dom进行路由。如果用户未通过身份验证,则转到“ http://localhost:3000/login”,成功登录后将其重定向到“ http://localhost:3000/dashboard”。重新加载此页面后,显示空白页面。

为解决此问题,我在基本URL之后添加了“ / app”,现在它在每个路由URL之前出现,现在内部页面路由就像“ http://localhost:3000/app/dashboard”一样。 但是我不想在每个路由元素之前添加“ app”, 我需要的路由网址应该是base_url / page路由路径。

空白页面路由::

import React, { Component } from 'react';
import { BrowserRouter, Route, Switch, Redirect } from 'react-router-dom';

const InitialPath = ({ component: Component, authUser, ...rest }) => {
   return (<Route
         {...rest}
         render={props =>
            authUser
               ? <Component {...props} />
               :
               <Redirect
                  to={{
                     pathname: '/login',
                     state: { from: props.location }
                  }}
               />
         }
      />
   )
}

class App extends Component {
   constructor(props) {
      super(props);
   }

   render() {
      let isUserLogggedIn = localStorage.getItem('isUserLoggedIn');
      const { location, match } = this.props;
      let url = location.pathname.split('/');
      if (location.pathname === '/login') {
         localStorage.clear();
      }
      if (location.pathname === '/') {
         if (!isUserLogggedIn) {
            return (<Redirect exact from='/' to={`${match.url}login`} />);
         } else {
            return (<Redirect exact from='/' to={`${match.url}app`} />);
         }
      }
      if ((url[1] !== "app") && (url[1] !== "login")) {
         return (<Redirect exact from={location.pathname} to={`${match.url}login`} />);
      }
      return (
         <>
            <BrowserRouter>
               <Switch>
                  <InitialPath
                     path={`${match.url}app`}
                     authUser={isUserLogggedIn}
                     component={DefaultLayout}
                     location={location}
                  />
                  <Route path='/login' component={Login} />
               </Switch>
            </BrowserRouter>
         </>
      );
   }
}

export default App;

如果从根目录中删除了“ app”,则其工作将继续并出现错误。

错误::

Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

1 个答案:

答案 0 :(得分:0)

我认为网址不是问题。

尝试将localStorage的内容处理成render方法不是最好的主意。您应该为此使用生命周期方法,即componentDidMountcomponentDidUpdate

您的App组件似乎被逻辑所淹没。身份验证逻辑应放入Login组件中,在安装(Login)时应清除存储。用户成功进行身份验证后,它(Login)应该将会话ID保存到存储中。

接下来的事情是不必自己弄乱位置,让react-router为您完成。

class App extends Component {
  componentDidUpdate () {
    this.setState({ isUserLoggedIn: !!localStorage.getItem("isUserLoggedIn") });
  }

  render () {
    const { isUserLogggedIn } = this.state;

    return (
      <BrowserRouter>
        <Switch>
          <InitialPath
            path="/dashboard"
            authUser={isUserLogggedIn}
            component={DefaultLayout}
            location={location}
          />
          <Route path="/login" component={Login} />
        </Switch>
      </BrowserRouter>
    );
  }
}

class Login extends Component {
  componentDidMount () {
    localStorage.removeItem("isUserLogggedIn");
  }

  render () {
    // some render stuff
    //
    // after successfull login
    // you should save `isUserLogggedIn` into localStorage 
    // and redirect to the main page
  }
}