首页 文章

React:根据登录状态有条件地在路径中渲染组件,而不显示加载页面

提问于
浏览
0

我正在尝试根据登录状态有条件地呈现组件 . 我单击一个单独组件的链接将我带回家('/'路线) . 如果登录,我希望这会带我直接进入'登录'家中,如果没有,请带我去'退出'家 .

加载页面的问题是它非常笨重 . 应用程序的其余部分立即加载 . 在没有加载页面的情况下直接在某些应用程序中“回家”的能力似乎应该很容易实现?可能的解决办法是:

  • 有条件地在某个点渲染路线,而不是路线下的组件

  • 显示上次呈现的组件,直到检索到数据,而不是加载页面 .

加载页面的当前代码如下 .

谢谢!

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            loading: true,
            auth: false
        };
    }
    
    componentDidMount() { // check to see if already signed in.
        firebase.auth.onAuthStateChanged((user) => {
            if (user) {
                this.setState({auth: user});
            } else {
                this.setState({auth: false});
            }
            this.setState({loading: false});
        });
    }
    
    render() {
        console.log(this.state.auth)
        return (
            <Router>
                <OuterContainer>
                    {
                        this.state.loading ?
                            <LoadingPage />
                        :
                            this.state.auth ?
                                <HomeLoggedIn /> :
                                <HomeLoggedOut />
                        
                    }
                    {
                        this.props.showPopupWithParams ?
                        <EditDictionaryPopup
                            dictionary={this.props.showPopupWithParams.dictionary}
                        />
                        : null
                    }
                </OuterContainer>
            </Router>
        )
    }
}

1 回答

  • 0

    首先,您需要在整个应用程序中管理状态,以便存储用户是否为LoggedIn或isAuthenticated . 如果你的应用程序变得更加复杂,试图通过管理最上层组件的状态来实现这一目标将会产生噩梦 . 尝试使用Redux或MobX或React Context API . 我假设您使用'auth'对象创建某种商店,以检查用户是否'isAuthenticated' .

    话虽这么说,你想要的是一个PrivateRoute组件 .

    // PrivateRoute.jsx
    import React from 'react';
    import { Route, Redirect } from 'react-router-dom';
    import { connect } from 'react-redux'; // if you're using Redux!
    import PropTypes from 'prop-types';
    
    const PrivateRoute = ({component: Component, auth, ...rest }) => (
      <Route
        {...rest}
        render = {props => 
          auth.isAuthenticated === true ? (
            <Component {...props} />
          ) : (
            <Redirect to="/loggedOutHome" />
          )
        }
      />
    );
    
    PrivateRoute.propTypes = {
      auth: PropTypes.object.isRequired,
    }
    
    // this would map your auth object to the components props with Redux
    const mapStateToProps = state => ({
      auth: state.auth,
    });
    
    export default connect(mapStateToProps)(PrivateRoute);
    

    然后,您将要在App组件中导入此PrivateRoute组件,并将其与react-router-dom的Switch一起用于您要保密的任何路由,并添加一些重新路由:

    // App.jsx
    import React, { Component } from 'react';
    import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
    
    import { default as PrivateRoute } from './components/PrivateRoute';
    import { Landing } from './components/Landing';
    import { LoggedInComponent } from "./components/LoggedInComponent";
    import { LoggedOutComponent } from "./components/LoggedOutComponent";
    
    class App extends Component {
      render() {
        return (
          <Router>
            <div className="App">
              <Route exact path="/" component={Landing} />
              <Route exact path="/loggedOutHome" component = {LoggedOutComponent} />
              <Switch>
                <PrivateRoute exact path="/loggedInHome" component={LoggedInComponent} />
              </Switch>
            </div>
          </Router>
        );
      }
    }
    
    export default App;
    

    现在,任何路由到LoggedInComponent的链接都将检查用户是否已经过身份验证,如果是,则将其带到那里,或者如果不是,则将其重定向到LoggedOutComponent .

    我希望这有帮助 .

相关问题