为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

守着一只汪 2022-07-21 21:12:58
我正在使用 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;
查看完整描述

3 回答

?
慕娘9325324

TA贡献1783条经验 获得超4个赞

这里最好的解决方案是在上下文提供程序中添加一个加载状态,一旦值更新就会重置。


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) */

   );

}


查看完整回答
反对 回复 2022-07-21
?
慕的地8271018

TA贡献1796条经验 获得超4个赞

我今天遇到了这个问题,我喜欢 Shubham 的做法。但是我解决它的方法只是userinfo从前一个组件中获取并将其传递给这个配置文件组件。


但是,请确保您Profile像这样渲染组件,以便确保userinfo存在:


function ParentComponent(){

 // do sth to get the userinfo here

return(

  <ParentComponent>

     {userinfo? <Profile userinfo={userinfo} /> : null}       

 <ParentComponent/>

)

}


查看完整回答
反对 回复 2022-07-21
?
红糖糍粑

TA贡献1815条经验 获得超6个赞

假设您正在设置如下上下文:


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>

);

}


查看完整回答
反对 回复 2022-07-21
  • 3 回答
  • 0 关注
  • 157 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信