我希望在多个页面上保持身份验证,但每次加载页面时,都会重新加载凭据,而不是看到已被检索。可能只是我误解了这将如何工作,但我很高兴听到有关此问题的最佳实践。
我正在使用 Firebase/Google 身份验证,并且
想使用他们的onAuthStateChanged
函数,存储不同页面之间的凭证信息。在我看来,这将被视为相同的“会话”,尽管我来自移动背景并且可能误解了网络概念。
onAuthStateChanged
每次我路由到一个不是最大交易的新页面时都会被点击,但我也希望保留我使用 Firebase 返回的信息获取的其他用户信息。因此,在每次加载页面时,onAuthStateChanged
都会被触发,并且没有任何持久性,因此我需要重新检索我需要的其他用户信息。
我会列出代码,然后进一步澄清问题。
首先,我有自己的 App 类:
import React, { useEffect } from 'react'
import Navigation from './components/Navbar'
import Routes from './Routes'
import { AuthProvider } from './services/contexts/AuthContext'
function App() {
return (
<AuthProvider>
<Navigation />
<Routes />
</AuthProvider>
)
}
export default App
路线非常简单。为简洁起见,它类似于:
import React, { Component } from 'react'
import { Router, Switch, Route } from 'react-router-dom'
import Home from './pages/Home'
import history from './history'
import Pricing from './pages/Pricing'
import PrivateRoute from './PrivateRoute'
import Account from './pages/Account'
export default class Routes extends Component {
render() {
return (
<Router history={history}>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/pricing" component={Pricing} />
<PrivateRoute path="/account" component={Account} />
</Switch>
</Router>
)
}
}
导航就像:
import React from 'react'
import { Navbar, Nav } from 'react-bootstrap'
import { withRouter } from 'react-router-dom'
import { useAuth } from '../services/contexts/AuthContext'
const Navigation = (props) => {
const { currentUser } = useAuth()
// console.log(props)
return (
<Navbar className="navbarColor" variant="dark">
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="mr-auto">
<Nav.Link href="/">Home</Nav.Link>
{!currentUser && <Nav.Link href="/pricing">Pricing</Nav.Link>}
{currentUser && <Nav.Link href="/account">Account</Nav.Link>}
</Nav>
</Navbar.Collapse>
</Navbar>
)
}
export default withRouter(Navigation)
最后,授权处理看起来像这样:
import React, { useContext, useEffect, useState } from 'react'
import { auth } from '../Authentication/firebase'
const AuthContext = React.createContext()
export function useAuth() {
return useContext(AuthContext)
}
export const AuthProvider = ({ children }) => {
const [currentUser, setCurrentUser] = useState()
const [loading, setLoading] = useState(true)
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(async (user) => {
console.log('setting up user')
setCurrentUser(user)
// Fetch other user information, like subscription, from my own database
setLoading(false)
})
return unsubscribe
}, [])
const value = {
currentUser
}
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
)
}
我已将 onAuthStateChanged
放在 useEffect
中,并将路由器包裹在 AuthContext
中,这让我认为任何路由都会使用相同的上下文,因此 {{1} } (不带参数)不会被再次调用。并不是 useEffect
被多次触发,而是整个组件似乎都被重新创建,让我觉得这个问题可能与我错误地做了一些事情有关,而不必绝对重新渲染一切。
我希望这很清楚;如果我需要澄清任何事情或提供任何进一步的信息,请告诉我。
我意识到它没有按照我想要的方式“加载”的部分原因是我进行身份验证设置的方式,在 useEffect
被标记为 true 之前不会返回子视图。至少在视觉上我通过添加 loading
改进了这一点,以便某些共享元素(如导航栏)可以在等待身份验证过程时加载。
这本身并不是我的问题的答案,所以听到人们如何以最佳方式处理存储身份验证仍然很高兴。