React/React Context API:使用 useEffect() 钩子时等待上下文值

我正在使用 React 开发一个 Web 应用程序,这就是我想要做的:

  1. 在最高阶组件中,检查用户是否已登录,如果已登录,则更新 'userinfo' 上下文值。

  2. 在 Profile.js 中,获取 'userinfo' 上下文值。

  3. 检查'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;


守着一只汪
浏览 162回答 3
3回答

慕娘9325324

这里最好的解决方案是在上下文提供程序中添加一个加载状态,一旦值更新就会重置。function Profile(props) {&nbsp; &nbsp;const {userinfo, loading, setuserinfo}=useContext(Userinfo);&nbsp; &nbsp;useEffect(()=>{&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if(!loading) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ((userinfo==null)?&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/*API call A (When user is not logged in) */ :&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /*API call B (When user is logged in) */&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )&nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; )},[loading, userinfo])&nbsp;&nbsp;&nbsp; &nbsp;if(loading) return <Loader />&nbsp; &nbsp;return (&nbsp; &nbsp; &nbsp; &nbsp;(userinfo==null)?&nbsp; &nbsp; &nbsp; &nbsp;/*Elements to render when user is not logged in) */ :&nbsp; &nbsp; &nbsp; &nbsp;/*Elements to render when user is&nbsp; logged in) */&nbsp; &nbsp;);}

慕的地8271018

我今天遇到了这个问题,我喜欢 Shubham 的做法。但是我解决它的方法只是userinfo从前一个组件中获取并将其传递给这个配置文件组件。但是,请确保您Profile像这样渲染组件,以便确保userinfo存在:function ParentComponent(){&nbsp;// do sth to get the userinfo herereturn(&nbsp; <ParentComponent>&nbsp; &nbsp; &nbsp;{userinfo? <Profile userinfo={userinfo} /> : null}&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<ParentComponent/>)}

红糖糍粑

假设您正在设置如下上下文:import React from 'react';const AuthContext = React.createContext({&nbsp; &nbsp; userInfo: null,&nbsp; &nbsp; isLoggedIn: false,&nbsp; &nbsp; loading: true,&nbsp; &nbsp; setUser: () => {}&nbsp;});export default AuthContext;您正在像这样设置您的全球提供商:import React from 'react';import&nbsp; AuthContext&nbsp; from './AuthContext'; // path to the contextexport default class GlobalUserContext extends React.Component{&nbsp; &nbsp; constructor(props){&nbsp; &nbsp; &nbsp; &nbsp; super(props);&nbsp; &nbsp; &nbsp; &nbsp; this.state = {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; userInfo: null,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isLoggedIn: false,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; loading: true&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; componentDidMount(){&nbsp; &nbsp; &nbsp; &nbsp; ( async() => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const currentUser = await getUser(); // say you are trying to log user in&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(currentUser){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.setState({&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; userinfo: currentUser,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isLoggedIn: true,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; loading: false&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; } )();&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; setUser = (user, check) => {&nbsp; &nbsp; &nbsp; &nbsp; this.setState({userInfo: user, isLoggedIn: check});&nbsp; &nbsp; };&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; render(){&nbsp; &nbsp; &nbsp; &nbsp; return (&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <AuthContext.Provider&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value={{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; user: this.state.user,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setUser: this.setUser,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isLoggedIn: this.state.isLoggedIn,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; loading: this.state.loading&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }}>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {this.props.children}&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </AuthContext.Provider>&nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; }}然后在使用的功能组件中useEffect,您可以执行以下操作:import React, { useContext, useEffect} from 'react';import AuthContext&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;from '../../contexts/AuthContext'; // your content pathexport 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&nbsp;// UserInfo is available}}, [userInfo, loading]);return (<View>{anything}</View>);}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript