React/React Context API:使用 useEffect() 钩子时等待上下文值
Posted
技术标签:
【中文标题】React/React Context API:使用 useEffect() 钩子时等待上下文值【英文标题】:React/React Context API: Wait for context values when using useEffect() hook 【发布时间】:2020-08-12 04:50:03 【问题描述】:我正在使用 React 开发一个 Web 应用程序,这就是我想要做的:
-
在最高阶组件中,检查用户是否已登录,如果已登录,则更新 'userinfo' 上下文值。
在 Profile.js 中,获取 'userinfo' 上下文值。
检查'userinfo'是否为空,并相应调用不同的API。
我写了下面的代码。问题在于,将 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;
【问题讨论】:
【参考方案1】:这里最好的解决方案是在上下文提供程序中添加一个加载状态,一旦值更新,它就会重置。
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) */
);
【讨论】:
【参考方案2】:我今天遇到了这个问题,我喜欢 Shubham 的做法。但是我解决它的方法只是从前一个组件中获取userinfo
并将其传递给这个配置文件组件。
但是,请确保像这样渲染 Profile
组件,以便确保 userinfo
存在:
function ParentComponent()
// do sth to get the userinfo here
return(
<ParentComponent>
userinfo? <Profile userinfo=userinfo /> : null
<ParentComponent/>
)
【讨论】:
【参考方案3】:假设您正在设置如下上下文:
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>
);
【讨论】:
以上是关于React/React Context API:使用 useEffect() 钩子时等待上下文值的主要内容,如果未能解决你的问题,请参考以下文章
React - 是不是在 useEffect 中调用 API
[react] react有几种构建组件的方式?可以写出来吗?
relativeLayout.setBackground(ContextCompat.getDrawable(context, R.drawable.sample_drawable));正在使 API