使用Firebase身份验证刷新受保护的路由React Router

Vin*_*ros 4 reactjs react-router firebase-authentication react-redux react-router-v4

我正在使用Firebase,React和Redux构建Todo Web应用程序。所以,我有保护rotes如"/todos/add""/dashboard"客人路线为"/""/signup""/login"至极不能是接取,如果你进行身份验证。我的问题是,当我在"/todos/add"路由中通过身份验证时,我重新加载了应用程序重新加载的页面,并且调度了我的auth操作,将我的用户放置在redux存储中,但是我重定向到"/login"then到"/dashboard"。但我想在重新加载之前在同一页面上。我的代码:

PrivateRoute.js

import React from "react";
import { connect } from "react-redux";
import { Route, Redirect } from "react-router-dom";
import PropTypes from "prop-types";

const PrivateRoute = ({
  isAuthenticated,
  isLoading,
  component: Component,
  ...rest
}) => (
  <Route
    {...rest}
    render={props =>
      isAuthenticated ? (
        <Component {...props} {...rest} />
      ) : (
        <Redirect to="/login" />
      )
    }
  />
);
const mapStateToProps = state => ({
  isAuthenticated: !!state.user.uid,
  isLoading: state.user.isLoading
 });

PrivateRoute.propTypes = {
  component: PropTypes.func.isRequired,
  isAuthenticated: PropTypes.bool.isRequired,
   isLoading: PropTypes.bool.isRequired
};

export default connect(mapStateToProps)(PrivateRoute);
Run Code Online (Sandbox Code Playgroud)

GuestRoute.js

import React from "react";
import { connect } from "react-redux";
import { Route, Redirect } from "react-router-dom";
import PropTypes from "prop-types";

const GuestRoute = ({ isAuthenticated, component: Component, ...rest }) => (
  <Route
    {...rest}
    render={props =>
      !isAuthenticated ? (
        <Component {...props} />
      ) : (
        <Redirect
          to="/dashboard"
        />
      )
    }
  />
);

const mapStateToProps = state => ({
  isAuthenticated: !!state.user.uid,
  isLoading: !!state.user.isLoading
});

GuestRoute.propTypes = {
  component: PropTypes.func.isRequired,
  isAuthenticated: PropTypes.bool.isRequired,
  isLoading: PropTypes.bool.isRequired
};

export default connect(mapStateToProps)(GuestRoute);
Run Code Online (Sandbox Code Playgroud)

App.js

import React from "react";
import { Route, Switch } from "react-router-dom";

// COMPONENTS
import HomePage from "./components/pages/homepage/HomePage";
import SignupPage from "./components/pages/signuppage/SignupPage";
import LoginPage from "./components/pages/loginpage/LoginPage";
import DashboardPage from "./components/pages/dashboardpage/DashboardPage";

// HOC
import Layout from "./components/hoc/layout/Layout";

// ROUTES
import PrivateRoute from "./routes/PrivateRoute";
import GuestRoute from "./routes/GuestRoute";
import AddTodosPage from "./components/pages/todos/add/AddTodosPage";

const App = () => (
  <Layout>
    <Switch>
      <Route path="/" exact component={HomePage} />
      <GuestRoute path="/signup" exact component={SignupPage} />
      <GuestRoute path="/login" exact component={LoginPage} />
      <PrivateRoute path="/todos/add" exact component={AddTodosPage} />
      <PrivateRoute path="/dashboard" exact component={DashboardPage} />
    </Switch>
  </Layout>
);

export default App;
Run Code Online (Sandbox Code Playgroud)

Cha*_*a94 5

FIX默认情况下
设置isLoadingtrue刷新时的值。(在Firebase身份验证后设置isLoadingfalse。)并且条件<PrivateRoute>应为(isLoading || isAuthenticated )
但很重要:在Firebase身份验证响应后,此处isLoadingisAuthenticated应一起设置。或isAuthenticated应在设置为之前isLoading进行相应设置false

说明
只要你在刷新<PrivateRoute>/todos/add,它会寻找isAuthenticated价值。似乎是false,因此将被重定向到/loginroute。
<GuestRoute>/login,它会再次查看!isAuthenticated价值。到这个时候,isAuthenticated价值似乎是true使其重定向回/dashboard

因此,从该观察结果可以看出,该isAuthenticated值未立即设置true为刷新。但是,此Firebase身份验证请求是异步操作,在该操作中会有一些值得注意的响应。但是在响应之前,重定向会以默认isAuthenticated值或undefined作为值发生。在此重定向之间,将完成Firebase身份验证调用并将其设置isAuthenticatedtrue,以最终重定向到/dashboard

但是这里利用isLoading值来延迟重定向。设置isLoadingtrue默认值,即刷新时的值。(在Firebase身份验证后设置isLoadingfalse。)并且条件<PrivateRoute>应为(isLoading || isAuthenticated )重要说明:在Firebase身份验证响应后,此处isLoadingisAuthenticated应一起设置。或isAuthenticated应在设置为之前isLoading进行相应设置false。(否则,如果isLoading设置为false,如果isAuthenticated仍然保留falseundefined则将被重定向!)