UseEffect 获取用户编号并在取消订阅时传递给 CurrentUser 状态(执行顺序)
UseEffect to fetch user number and pass to CurrentUser state on unsubscribe (order of execution)
我正在使用 Firebase 对用户进行身份验证,然后使用 Firebase ID (uid) 通过 HTTP 请求将用户数据设置为 Postgres 中的用户行。它按书面方式工作,但我在执行这些功能的顺序时遇到问题,因为控制台正在 returning 'invalid input syntax for type integer: "undefined"'.
所需的顺序是
- 等待认证到return一个uid
- 使用 uid 执行 HTTP 请求
- 重定向到“/”
相反,它似乎 运行 2, 1, 3, 2。在第二次 HTTP 尝试时填充数据。这就解释了为什么我有时需要注销并重新登录某些组件才能加载用户数据。
我缺少什么来确保正确的操作顺序?
Login.js
async function handleSubmit(e) {
e.preventDefault()
try {
setError("")
setLoading(true)
await login(emailRef.current.value, passwordRef.current.value)
setLoading(false)
history.push("/")
} catch {
setLoading(false)
setError("Failed to log in")
}
Auth.js
useEffect(() => {
const fetchProfile = (uid) => {
axios.get(`/user/${uid}`)
.then(async (response) => {
setUserData(await response.data)
console.log(response.data)
console.log(uid)
})
.catch(error => console.error(`Error: ${error}`))
}
const unsubscribe = auth.onAuthStateChanged(async user => {
user && fetchProfile(user.uid)
setCurrentUser(user)
setLoading(false)
})
return unsubscribe
}, [])
const value = {
currentUser,
userData,
login,
signup,
logout,
resetPassword,
updateEmail,
updatePassword
}
return (
<AuthContext.Provider value={value}>
{ !loading && children}
</AuthContext.Provider>
)
我会删除 fetchProfile
作为函数并将 unsubscribe
移到 useEffect
之外,并将 currentUser
作为 useEffect
的依赖项。当 currentUser
发生变化时,useEffect
只会 运行。
...
const unsubscribe = auth.onAuthStateChanged(async user => {
//only if there is a user setCurrentUser
if(user){
setCurrentUser(user)
setLoading(false)
}
})
useEffect(() => {
if(!currentUser) return
axios.get(`/user/${currentUser.uid}`)
.then(async (response) => {
setUserData(await response.data)
console.log(response.data)
console.log(uid)
})
.catch(error => console.error(`Error: ${error}`))
}, [currentUser])
...
我正在使用 Firebase 对用户进行身份验证,然后使用 Firebase ID (uid) 通过 HTTP 请求将用户数据设置为 Postgres 中的用户行。它按书面方式工作,但我在执行这些功能的顺序时遇到问题,因为控制台正在 returning 'invalid input syntax for type integer: "undefined"'.
所需的顺序是
- 等待认证到return一个uid
- 使用 uid 执行 HTTP 请求
- 重定向到“/”
相反,它似乎 运行 2, 1, 3, 2。在第二次 HTTP 尝试时填充数据。这就解释了为什么我有时需要注销并重新登录某些组件才能加载用户数据。
我缺少什么来确保正确的操作顺序?
Login.js
async function handleSubmit(e) {
e.preventDefault()
try {
setError("")
setLoading(true)
await login(emailRef.current.value, passwordRef.current.value)
setLoading(false)
history.push("/")
} catch {
setLoading(false)
setError("Failed to log in")
}
Auth.js
useEffect(() => {
const fetchProfile = (uid) => {
axios.get(`/user/${uid}`)
.then(async (response) => {
setUserData(await response.data)
console.log(response.data)
console.log(uid)
})
.catch(error => console.error(`Error: ${error}`))
}
const unsubscribe = auth.onAuthStateChanged(async user => {
user && fetchProfile(user.uid)
setCurrentUser(user)
setLoading(false)
})
return unsubscribe
}, [])
const value = {
currentUser,
userData,
login,
signup,
logout,
resetPassword,
updateEmail,
updatePassword
}
return (
<AuthContext.Provider value={value}>
{ !loading && children}
</AuthContext.Provider>
)
我会删除 fetchProfile
作为函数并将 unsubscribe
移到 useEffect
之外,并将 currentUser
作为 useEffect
的依赖项。当 currentUser
发生变化时,useEffect
只会 运行。
...
const unsubscribe = auth.onAuthStateChanged(async user => {
//only if there is a user setCurrentUser
if(user){
setCurrentUser(user)
setLoading(false)
}
})
useEffect(() => {
if(!currentUser) return
axios.get(`/user/${currentUser.uid}`)
.then(async (response) => {
setUserData(await response.data)
console.log(response.data)
console.log(uid)
})
.catch(error => console.error(`Error: ${error}`))
}, [currentUser])
...