即时反应上下文 api 更新状态
Posted
技术标签:
【中文标题】即时反应上下文 api 更新状态【英文标题】:React context api update state instantly 【发布时间】:2020-08-01 10:15:20 【问题描述】:我在 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
当我第一次加载页面或重新加载页面时,我的 IndexPage
组件中的 console.log
的结果如下:
app userIsLoggedIn: false
app userIsLoggedIn: true
这意味着我的页面正在重新呈现,并且我的内容在用户登录时隐藏/显示的内容之间闪烁。有没有办法避免这种情况并使状态更加即时?我愿意接受任何建议:)
【问题讨论】:
尝试改变 useEffectauthListener
逻辑如this
【参考方案1】:
好的,我找到了对我的具体案例有帮助的方法。我没有使用上下文 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
函数会立即刷新它。
【讨论】:
以上是关于即时反应上下文 api 更新状态的主要内容,如果未能解决你的问题,请参考以下文章