我正在使用 firebase、react 和 redux 构建一个待办事项 Web 应用程序。因此,我保护了诸如 "/todos/add"
、"/dashboard"
等死记硬背,以及 "/"
, guest 路线“/signup”
、“/login”
如果您通过身份验证,则无法访问。
我的问题是,当我在 "/todos/add"
路由中进行身份验证时,我重新加载应用程序重新加载的页面,并且调度我的身份验证操作,将我的用户放入 redux 存储中,但是我重定向到 "/login"
,然后重定向到 "/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);
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);
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;
最佳答案
修复
设置isLoading
至true
默认情况下,这将是刷新时的值。 (在 Firebase 身份验证后将 isLoading
设置为 false
。)以及 <PrivateRoute>
中的条件。应该是(isLoading || isAuthenticated )
。
但重要的是:这里isLoading
和isAuthenticated
应在 firebase 身份验证响应后一起设置。或isAuthenticated
应在 isLoading
之前进行相应设置设置为false
.
说明
一旦刷新<PrivateRoute>
的/todos/add
,它会寻找 isAuthenticated
值(value)。这里似乎是 false
,因此将被重定向到 /login
路线。
当在<GuestRoute>
时的/login
,它会再次查看 !isAuthenticated
值(value)。此时isAuthenticated
值似乎是 true
使其重定向回 /dashboard
.
所以从这个观察可以看出isAuthenticated
值未设置为true
一刷新。相反,这个 firebase 身份验证请求是异步操作,其中会有一些值得注意的响应。但在响应之前,会发生重定向,默认为 isAuthenticated
值或 undefined
作为值(value)。在此重定向之间,将完成 Firebase 身份验证调用并设置 isAuthenticated
至true
最终重定向到/dashboard
.
但是这里使用isLoading
延迟重定向的值。设置isLoading
至true
默认情况下,这将是刷新时的值。 (在 Firebase 身份验证后将 isLoading
设置为 false
。)以及 <PrivateRoute>
中的条件。应该是(isLoading || isAuthenticated )
。 重要:此处isLoading
和isAuthenticated
应在 firebase 身份验证响应后一起设置。或isAuthenticated
应在 isLoading
之前进行相应设置设置为false
。 (否则,如果 isLoading
设置为 false
并且 isAuthenticated
仍然保留 false
或 undefined
它将被重定向!)
关于reactjs - 使用 firebase auth 刷新 protected 路由 React Router,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49091416/