在React Native应用中,我有一个Login组件,它将userId存储在应用上下文中。登录后,用户将转到Dashboard组件,在该组件中使用useContext钩子访问userId。从数据库中获取帖子时需要userId。在组件装载时,我使用useEffect钩子调用获取函数。
问题是当useEffect执行并调用函数时,userId是未定义的。但是,如果我重新呈现组件,那么我可以通过日志看到,现在已经定义了id,但是因为useEffect已经执行,所以我没有从服务器获取数据。我已经尝试使用setTimeOut来解决这个问题()方法,但同样是在定义id之前进行提取。
最让我感到奇怪的是,在 Jmeter 板组件中,我按照相同的步骤从上下文访问令牌,这个令牌立即可用。
下面,我给你看我的代码和应用程序的日志:
This is the Context file
//AuthContext.tsx
import { createContext, useState } from "react";
import { AuthUser } from "../types/AuthUser";
type AuthContextProviderProps = {
children: React.ReactNode
}
type AuthContextType= {
isAuthenticated : boolean
setIsAuthenticated : React.Dispatch<React.SetStateAction<boolean>>
token : string
setToken : React.Dispatch<React.SetStateAction<string>>
userId : string
setUserId : React.Dispatch<React.SetStateAction<string>>
userName : string
setUserName : React.Dispatch<React.SetStateAction<string>>
}
export const AuthContext = createContext({} as AuthContextType)
export const AuthContextProvider = ({children}: AuthContextProviderProps)=>{
const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false)
const [token, setToken] = useState<string>('')
const [userId, setUserId] = useState<string>('')
const [userName, setUserName] = useState<string>('')
//const [authUser, setAuthUser] = useState<AuthUser>({userId:'', userName:''})
return(
<AuthContext.Provider value={{isAuthenticated, setIsAuthenticated,token, setToken, userId,setUserId,userName,setUserName}}>
{children}
</AuthContext.Provider>
)
}
在Login屏幕中,我将userId和token存储在Context中
const loginUser = async(): Promise<ISuccessFullResponse | boolean>=>{
try {
const body = {email, password}
const url = REMOTE_SERVER+'/authentication/loginUser'
console.log(url)
const response = await fetch(url,{
method : 'POST',
headers:{'content-type':'application/json'},
body : JSON.stringify(body)
})
console.log(loggedUser)
const id = loggedUser.data.user._id
const name = loggedUser.data.user.userName
setToken(loggedUser.data.token)
setUserId(id)
setUserName(name)
return loggedUser
} catch (error) {
console.log(error)
}
return false
}
}
登录后,将重定向到 Jmeter 板。“”“const Jmeter 板:ReactFC =(支持)=〉{
//interfaces
interface IPost{
contentString : string
urls : string[]
}
//global state
const authContext = useContext(AuthContext)
const token = authContext.token
console.log('token in dashboard', token)
const id = authContext.userId
console.log('id in dashboard', id)
const profilePicContext = useContext(ProfilePicContext)
const setProfilePic = profilePicContext.setProfilePic
//local state
const [arrayOfPosts, setArrayOfPosts] = useState<IPost[]>([])
const [status, setStatus] = useState<string>('')
const [errMsg, setErrMsg] = useState<string>("")
//props
const navigation = props.navigation
//function definitions
const getProfilePicture = async():Promise<boolean>=>{
try {
const response = await fetch(REMOTE_SERVER+'/dashboard/downloadProfilePicture', {
headers : {token}
})
const parseResponse = await response.json()
if(parseResponse.data){
setProfilePic(parseResponse.data)
}
} catch (error) {
console.log(error)
if(error instanceof Error){
console.log('this is the error',error)
return false
}
}
return true
}
const getPostsFromFollowingUsers = async():Promise<boolean>=>{
setStatus('LOADING')
try {
console.log('inside function id', id)
const response = await fetch(REMOTE_SERVER+`/userPost/getPostsFromFollowingUsers/${id}`, {
method : 'GET',
headers : {'Content-Type': 'application/json'}
})
const parseResponse = await response.text()
console.log('this is the parseresponse',parseResponse)
const responseObject = JSON.parse(parseResponse)
if(responseObject.data){
setArrayOfPosts(responseObject.data)
}
} catch (error) {
console.log('this is the error',error)
setStatus('ERROR')
if(error instanceof Error){
setErrMsg(error.message)
}
}
return true
}
useEffect(()=>{
getProfilePicture()
}, [])
useEffect(()=>{
getPostsFromFollowingUsers()
}, [])
return(
'''如您所见,常量标记的存储和访问方式与userId相同,但该标记在 Jmeter 板中可访问,并在getProfilePicture()中成功使用。另一方面,userId最初未定义,在调用getPostFromFollowingUsers()后变为已定义。以下是日志:
token in dashboard eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiNjJkMTg1YjI2NTliZDEzMjlhNDVjMzBkIiwiaWF0IjoxNjczODAzMDQ5LCJleHAiOjE2NzM4MzkwNDl9.HdJn0YAfi-yM9wPZMek6zmw4SUE2TsR_AzUOK06MeBg
LOG id in dashboard
LOG name in dashboard
LOG inside function id
LOG token in dashboard eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiNjJkMTg1YjI2NTliZDEzMjlhNDVjMzBkIiwiaWF0IjoxNjczODAzMDQ5LCJleHAiOjE2NzM4MzkwNDl9.HdJn0YAfi-yM9wPZMek6zmw4SUE2TsR_AzUOK06MeBg
LOG id in dashboard 62d185b2659bd1329a45c30d
LOG name in dashboard
LOG token in dashboard eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiNjJkMTg1YjI2NTliZDEzMjlhNDVjMzBkIiwiaWF0IjoxNjczODAzMDQ5LCJleHAiOjE2NzM4MzkwNDl9.HdJn0YAfi-yM9wPZMek6zmw4SUE2TsR_AzUOK06MeBg
LOG id in dashboard 62d185b2659bd1329a45c30d
LOG name in dashboard Joaquin
LOG token in dashboard eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiNjJkMTg1YjI2NTliZDEzMjlhNDVjMzBkIiwiaWF0IjoxNjczODAzMDQ5LCJleHAiOjE2NzM4MzkwNDl9.HdJn0YAfi-yM9wPZMek6zmw4SUE2TsR_AzUOK06MeBg
LOG id in dashboard 62d185b2659bd1329a45c30d
LOG name in dashboard Joaquin
LOG this is the parseresponse <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET /userPost/getPostsFromFollowingUsers/</pre>
</body>
</html>
LOG this is the error [SyntaxError: JSON Parse error: Unrecognized token '<']
当然,路由需要一个参数才能工作,这就是为什么我得到这个错误。现在id I type a space in Visual Studio Code useEffect被再次调用,现在userId被定义,这样就可以执行提取并从服务器检索数据。如果有人分享了如何解决这个问题的想法,我将不胜感激。
1条答案
按热度按时间yr9zkbsy1#
添加一个加载状态到你的组件,当你获取数据时设置为true,然后当数据被获取时设置为false,当活动加载器加载时显示它,这可能会解决你的问题。