javascript - react : Conditionally render a component in a route based on login status, 而不显示加载页面

标签 javascript reactjs react-router jsx

我正在尝试根据登录状态有条件地呈现组件。我单击单独组件中的链接将我带回家(“/”路线)。如果已登录,我希望它直接带我到“登录”主页,如果没有,则带我到“注销”主页。

加载页面的问题是它非常笨拙。应用程序的其余部分会立即加载。在某些应用程序中直接进入“主页”而无需加载页面的能力似乎应该很容易实现?可能的解决方案可能是:

  • 在某个时刻有条件地渲染路由,而不是路由下的组件
  • 在检索数据之前显示最后渲染的组件,而不是加载页面。

编辑:我希望“/”路由显示 HomeLoggedIn 或 HomeLoggedOut 但不重定向到另一个路由,以便两个组件的 url 相同。

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

谢谢!

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>
        )
    }
}

最佳答案

首先,您需要管理整个应用程序的状态,以便存储用户是否已登录或已验证。如果您的应用程序变得更加复杂,那么尝试通过管理最上层组件的状态来实现这一点将会造成噩梦。尝试 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);

然后,您需要在应用程序组件中导入此 PrivateRoute 组件,并在您想要保持私有(private)的任何路线上使用它以及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。

我希望这会有所帮助。

关于javascript - react : Conditionally render a component in a route based on login status, 而不显示加载页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53701480/

相关文章:

javascript - Firefox .naturalHeight 属性

javascript - 使用 redux 表单添加和编辑多个主题

javascript - 如何将 webpack 插件添加到react-rewired

javascript - 在我的 React 项目中获取 "Cannot call a class as a function"

javascript - 与自定义路由 react (在 Symfony 后端)

javascript - 使用 React 自动重定向?

javascript - 使 React 组件/div 可拖动的推荐方法

javascript - 检查 jQuery slider 的最后一个子项

javascript - 如何根据滚动位置逐步变换元素

javascript - 使用给定的 Redux 状态加载 React 应用程序?