我正在Gatsby设置中使用上下文api来跟踪称为userIsLoggedIn
的状态。我正在使用Firebase进行身份验证。
这是我的上下文文件:
import { createContext } from "react"
export const AppContext = createContext(null)
这是我的AppWrapper组件:
import React, { useState, useEffect } from "react"
import firebase from "../../config/firebase"
import { AppContext } from "../../context/AppContext"
const AppWrapper = ({ children }: any) => {
const [userIsLoggedIn, setUserIsLoggedIn] = useState(false)
const authListener = () => {
firebase.auth().onAuthStateChanged(user => {
if (user && user.emailVerified) {
setUserIsLoggedIn(true)
} else {
setUserIsLoggedIn(false)
}
})
}
useEffect(() => {
authListener()
}, [])
return (
<>
<AppContext.Provider
value={{
userIsLoggedIn,
}}
>
<main>{children}</main>
</AppContext.Provider>
</>
)
}
export default AppWrapper
这是我的索引页面,我要在该页面上跟踪用户是否登录,以便我可以显示/隐藏某些内容:
import React, { useContext } from "react"
import { AppContext } from "../context/AppContext"
const IndexPage = () => {
const app = useContext(AppContext)
console.log("app", app)
return (
<>
{app && app.userIsLoggedIn && (
<>
<h1>Hello dearest user</h1>
<p>Welcome to your page.</p>
</>
)}
</>
)
}
export default IndexPage
当我第一次加载页面或重新加载页面时,console.log
组件中IndexPage
的结果如下:
app {userIsLoggedIn: false}
app {userIsLoggedIn: true}
这意味着我的页面正在重新呈现,并且我的内容在用户登录时隐藏/显示的内容之间闪烁。是否有办法避免这种情况并使状态更加即时?我愿意接受任何建议:)
答案 0 :(得分:0)
好的,所以我发现了对我的具体情况有用的东西。我没有使用上下文api来保持应用程序状态(重新加载时将重置为默认值,因此状态之间会闪烁),如果用户与我的authListener
函数一起登录,我将使用localStorage进行保存
这是我添加的auth util
:
// Firebase
import firebase from "../config/firebase"
export const isBrowser = () => typeof window !== "undefined"
export const getUser = () => {
if (isBrowser()) {
const user = window.localStorage.getItem("user")
if (user !== null) {
return JSON.parse(user)
} else {
return ""
}
}
}
export const setUser = (email: string | null) =>
isBrowser() && window.localStorage.setItem("user", JSON.stringify(email))
export const isLoggedIn = () => {
const user = getUser()
return !!user
}
export const logout = () => {
return new Promise(resolve => {
firebase
.auth()
.signOut()
.then(() => {
setUser("")
resolve()
})
})
}
在我的AppWrapper
函数中,我的authListener
函数如下所示:
import { setUser, logout } from "../../utils/auth"
const authListener = () => {
firebase.auth().onAuthStateChanged(user => {
if (user && user.emailVerified) {
setUser(user.email)
} else {
logout()
}
})
}
useEffect(() => {
authListener()
})
在我的应用程序中的任何地方,我都可以使用isLoggedIn()
实用程序来检查用户是否实际上已登录,而内容没有闪烁。
如果我手动删除或更改localStorage user
,则当应用程序发生任何更改时,它会立即通过authListener
函数进行刷新。