【发布时间】:2021-02-11 02:53:54
【问题描述】:
我有一个通过 React Router 定义路由的 React Web 应用。
应用上的身份验证是使用 Firebase 完成的,我想根据用户是否登录来保护某些路由。
为了判断用户是否登录,我使用了以下函数:
let user = firebase.auth().currentUser;
if (user) {
} else {
}
}
从那里,我认为我可以将“受保护”路由放入初始位置,如果这样可以确定用户是否已登录,如下所示:
let user = firebase.auth().currentUser;
if (user) {
<div>
<Route path="/dashboard" component={Dashboard} exact />
</div>
} else {
<Route path="/sign-in" component={SignIn} />
}
}
如果用户没有登录,那么他们将被重定向到登录组件。
但这不起作用。仪表板页面只是以空白屏幕的形式返回,而不是重定向。
确实,控制台中显示了一条错误消息:
警告:道具类型失败:提供给
Switch的道具children无效,需要 ReactNode。
作为参考,这是我的完整组件:
class App extends Component {
constructor(props) {
super(props)
this.userLoggedIn = this.userLoggedIn.bind(this)
}
userLoggedIn = () => {
let user = firebase.auth().currentUser;
if (user) {
<div>
<Route path="/dashboard" component={Dashboard} exact />
</div>
} else {
<Route path="/sign-in" component={SignIn} />
}
}
render() {
return (
<div>
<Switch>
{this.userLoggedIn}
<Route exact path="/" component={Homepage} />
<Route path="/sign-in" component={SignIn} />
<Route path="/register" component={Register} />
</Switch>
</div>
)
}
}
我知道逻辑有缺陷,但有没有办法可以重构我的代码来实现这个非常简单的 hack 以使用 Firebase Auth 获取受保护的路由?
希望这很清楚,如果需要更多信息,请告诉我。
编辑:根据答案编辑了我的代码,但现在收到以下错误消息:
TypeError: Right side of assignment cannot be destructured
PrivateRoute
src/PrivateRoute.js:8
5 | import { AuthContext } from './Auth'
6 |
7 | export default function PrivateRoute({ component: RouteComponent, ...rest }) {
> 8 | const {currentUser} = useContext(AuthContext)
9 | return (
10 | <Route
11 | {...rest}
我更新的代码...
Auth.js
import React, { useEffect, useState } from 'react'
import * as firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";
import firebaseConfig from './firebaseConfig';
export const AuthContext = React.createContext();
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState(null);
useEffect(() => {
firebase.auth().onAuthStateChanged(setCurrentUser);
}, []);
return (
<AuthContext.Provider
value={{currentUser}}
>
{children}
</AuthContext.Provider>
)
}
PrivateRoute.js
import React, { useContext } from 'react';
import { Route, Redirect } from 'react-router-dom';
import { AuthContext } from './Auth'
export default function PrivateRoute({ component: RouteComponent, ...rest }) {
const { currentUser } = useContext(AuthContext)
return (
<Route
{...rest}
render={routeProps =>
!!currentUser ? (
<RouteComponent {...routeProps} currentUser={currentUser} />
) : (
<Redirect to={'/signin'}/>
)
}
/>
)
}
App.js
import React, { Component } from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import PrivateRoute from './PrivateRoute';
import './App.css';
import * as firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";
import firebaseConfig from './firebaseConfig';
class App extends Component {
render() {
return (
<div>
<Switch>
<PrivateRoute path="/dashboard" component={Dashboard} />
<Route exact path="/" component={Homepage} />
<Route path="/sign-in" component={SignIn} />
<Route path="/register" component={Register} />
</Switch>
</div>
)
}
}
export default App;
【问题讨论】:
标签: javascript reactjs firebase firebase-authentication