React Router - 在页面刷新后保留当前路由

时间:2017-10-23 14:02:33

标签: reactjs react-router

我是SPA开发的新手。我使用React和React Router并制作了简单的应用程序。它有两个页面:public和protected。用户只有在登录时才能看到受保护的页面。我使用firebase来管理用户。

问题是,当我进入受保护页面,登录并可以看到其内容时,我重新刷新页面并重定向到“默认”状态,即公共页面。

index.js

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

App.js

const ProtectedPage = () => {
  return (
    <div>
      <h1> Protected page. </h1>
      <Link to="/">Public resources</Link>
    </div>
  );
}

const PublicPage = () => {
  return (
    <div>
      <h1> Public page. </h1>
      <p> Login to see protected resources </p>
      <Link to="/protected">Protected resources</Link>
    </div>
  );
}

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

class App extends React.Component {
  constructor(props) {
    super(props);

    this.login = this.login.bind(this);
    this.logout = this.logout.bind(this);

    this.state = {
      username: '',
      uuid: ''
    }
  }

  login() {
    auth.signInWithEmailAndPassword(email, password).then((user) => {
      console.log('Sign in ', user.displayName);
      this.setState({
        username: user.displayName,
        uuid: user.uuid
      });
    });
  }

  logout() {
    auth.signOut().then(() => {
      console.log('Sign out ');
      this.setState({
        username: '',
        uuid: '' 
      });
    })
  }

  componentDidMount() {
    this.releaseFirebaseAuthHandler = auth.onAuthStateChanged((user) => {
      if(user) {
        this.setState({
          username: user.displayName,
          uuid: user.uuid
        });
      }
    });
  }

  componentWillUnmount() {
    this.releaseFirebaseAuthHandler();
  }

  render() {
    return (
      <div>
        <div className="navbar">
          <nav className="navbar-nav">
            { this.state.username ? 
              <button onClick={this.logout}>Logout</button> :
              <button onClick={this.login}>Login</button> }
          </nav>
        </div>
        <div>
            <div>
              <Route exact path="/" component={PublicPage} />
              <PrivateRoute path="/protected" component={ProtectedPage} isAuthenticated={this.state.uuid !== ''} />
            </div>
        </div>
      </div>
    ); 
  }
}

export default App;

是否可以在不涉及服务器的情况下刷新localhost:3000 / protected页面?

2 个答案:

答案 0 :(得分:2)

如果用户未经过身份验证,则在您的代码中重定向到pathname: '/'

const PrivateRoute = (...) => (
  <Route {...rest} render={props => (
   isAuthenticated 
     ? <Component {...props}/>
     : <Redirect to={{
        pathname: '/',
        state: { from: props.location }
       }}/>
   )}/>
 )

如果您希望将/protected保留在网址中的一种方法,那就是将重定向替换为<div>Please login</div>

之类的内容

答案 1 :(得分:1)

多个会话不保留状态,为此您可以使用localStorage