[英]Why does my component render twice when using React's Context API and the useEffect hook?
[英]React/React Context API: Wait for context values when using useEffect() hook
我正在使用 React 開發 web 應用程序,這就是我想要做的:
我寫了下面的代碼。 問題在於,將 userinfo 上下文值傳遞給組件顯然存在時間滯后。 所以當使用 useEffect() hook 時,當 userinfo 不是 null 時 Profile.js 會渲染兩次。
有沒有辦法修復此代碼,使其等待“userinfo”變量,然后相應地調用相關 API,而不是之前?
下面是代碼。 有什么建議嗎? 提前非常感謝!
import React, {useEffect, useContext} from 'react';
import Userinfo from "../context/Userinfo";
function Profile(props) {
const {userinfo, setuserinfo}=useContext(Userinfo);
useEffect(()=>{
((userinfo==null)?
/*API call A (When user is not logged in) */ :
/*API call B (When user is logged in) */
)},[userinfo])
return (
(userinfo==null)?
/*Elements to render when user is not logged in) */ :
/*Elements to render when user is logged in) */
);
}
export default Profile;
這里最好的解決方案是在上下文提供程序中添加加載 state,一旦值更新,該提供程序就會重置。
function Profile(props) {
const {userinfo, loading, setuserinfo}=useContext(Userinfo);
useEffect(()=>{
if(!loading) {
((userinfo==null)?
/*API call A (When user is not logged in) */ :
/*API call B (When user is logged in) */
)
}
)},[loading, userinfo])
if(loading) return <Loader />
return (
(userinfo==null)?
/*Elements to render when user is not logged in) */ :
/*Elements to render when user is logged in) */
);
}
我今天遇到了這個問題,我喜歡 Shubham 的做法。 但是我解決它的方法只是從前一個組件中獲取userinfo
並將其傳遞給這個配置文件組件。
但是,請確保像這樣呈現Profile
組件,以便確保userinfo
存在:
function ParentComponent(){
// do sth to get the userinfo here
return(
<ParentComponent>
{userinfo? <Profile userinfo={userinfo} /> : null}
<ParentComponent/>
)
}
假設您正在設置如下上下文:
import React from 'react';
const AuthContext = React.createContext({
userInfo: null,
isLoggedIn: false,
loading: true,
setUser: () => {}
});
export default AuthContext;
您正在像這樣設置您的全球提供商:
import React from 'react';
import AuthContext from './AuthContext'; // path to the context
export default class GlobalUserContext extends React.Component{
constructor(props){
super(props);
this.state = {
userInfo: null,
isLoggedIn: false,
loading: true
}
}
componentDidMount(){
( async() => {
const currentUser = await getUser(); // say you are trying to log user in
if(currentUser){
this.setState({
userinfo: currentUser,
isLoggedIn: true,
loading: false
});
}
} )();
}
setUser = (user, check) => {
this.setState({userInfo: user, isLoggedIn: check});
};
render(){
return (
<AuthContext.Provider
value={{
user: this.state.user,
setUser: this.setUser,
isLoggedIn: this.state.isLoggedIn,
loading: this.state.loading
}}>
{this.props.children}
</AuthContext.Provider>
);
}
}
然后在使用useEffect
的功能組件中,您可以執行以下操作:
import React, { useContext, useEffect} from 'react';
import AuthContext from '../../contexts/AuthContext'; // your content path
export const MyComponent = () => {
const {userInfo, isLoggedIn, loading} = useContext(AuthContext);
useEffect(() => {
// here you can now ask if the user data is still loading like so:
if(!loading){
// do something
// UserInfo is available
}
}, [userInfo, loading]);
return (
<View>
{anything}
</View>
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.