[英]React/React Context API: Wait for context values when using useEffect() hook
I am developing a web app using React and here is what I am trying to do:我正在使用 React 开发 web 应用程序,这就是我想要做的:
I wrote the below code.我写了下面的代码。 The problem is that there is apparently a time lag for the userinfo context value to be delivered to the component.
问题在于,将 userinfo 上下文值传递给组件显然存在时间滞后。 So when using useEffect() hook, Profile.js will render twice when userinfo is not null.
所以当使用 useEffect() hook 时,当 userinfo 不是 null 时 Profile.js 会渲染两次。
Is there a way to fix this code so that it waits for 'userinfo' variable, and then call relevant APIs accordingly, not before?有没有办法修复此代码,使其等待“userinfo”变量,然后相应地调用相关 API,而不是之前?
Below is the code.下面是代码。 Any advice?
有什么建议吗? Thanks a lot in advance!
提前非常感谢!
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;
The best solution here is to add a loading state in the context provider which is reset once the value is updated.这里最好的解决方案是在上下文提供程序中添加加载 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) */
);
}
I have this problem today, I like what Shubham does.我今天遇到了这个问题,我喜欢 Shubham 的做法。 But the way I solve it is just getting the
userinfo
from the previous component and pass it to this profile component.但是我解决它的方法只是从前一个组件中获取
userinfo
并将其传递给这个配置文件组件。
However, make sure you render the Profile
component like this so that you can make sure the userinfo
exists:但是,请确保像这样呈现
Profile
组件,以便确保userinfo
存在:
function ParentComponent(){
// do sth to get the userinfo here
return(
<ParentComponent>
{userinfo? <Profile userinfo={userinfo} /> : null}
<ParentComponent/>
)
}
Lets assume you are setting up a context like below:假设您正在设置如下上下文:
import React from 'react';
const AuthContext = React.createContext({
userInfo: null,
isLoggedIn: false,
loading: true,
setUser: () => {}
});
export default AuthContext;
And you are setting up your Global Provider like this:您正在像这样设置您的全球提供商:
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>
);
}
}
Then in your functional component using useEffect
,you can do something like this:然后在使用
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.