Home > Software engineering >  Async request in useEffect doesn't work like async
Async request in useEffect doesn't work like async

Time:06-30

i'm trying to take data from a backend,it takes data , but it doesn't display data on the page until the component calls componentDidUpdate() , but with the second function it works. I think that the it mounting component before the taking data , i tried to use 'uselayouteffect' but it didn't solve the problem , by using console.log , i understood that the problem in the my async functions , but the functions are the same (i mean structure) .

useEffect : `

useEffect( () => {

    console.log('ProfileUseEffect')

    getUserInfo().then( (response) => {
        console.log(response)
    }).catch((error) => {
        console.log(error)
    })


    loadAllSessions().then( (response) => {
        console.log(response)
    }).catch((error) => {
        console.log(error)
    })

}, [])

`

function that doesn't work correctly :

    const getUserInfo = async () => {

    console.log('ThisShitGonnaWork')

    const requestData = {
        "client": requestClient,
        "key": requestKey,
        "data":{
            "action":"getInfo",
            "token": accessTokenCookie['access_token'],
        }
    }

    try{
        const response = await axios.post(
            backendUrl   'user' , requestData
        )

        setUserAccountInfo(response?.data?.message)

        typeof  userAccountInfo.userlogin !== 'undefined' &&  setUserLogin(userAccountInfo.userlogin)
        typeof  userAccountInfo.username !== 'undefined' &&  setUserName(userAccountInfo.username)
        typeof  userAccountInfo.userrole !== 'undefined' &&  setUserRole(userAccountInfo.userrole)

    }catch (err){
        console.log(err)
    }
    
}

function that works correctly :

    const loadAllSessions = async () => {
    
    const requestData = {
        "client": requestClient,
        "key": requestKey,
        "data":{
            "action":"getActiveSessions",
            "token": accessTokenCookie['access_token'],
        }
    }

    try{
        const response = await axios.post(
            backendUrl   'user', requestData
        )
        response?.data?.message?.activeSessions.forEach( (elem , idx ) => {
            updateUserSessionsMap(idx , elem)
        })

    }catch (err){
        console.log(err)
    }


}

I've been sitting here for almost a week now and have been scratching my head over this problem, I would be grateful if you could help me.

CodePudding user response:

It does not work because of this part:

 try{
        const response = await axios.post(
            backendUrl   'user' , requestData
        )

        setUserAccountInfo(response?.data?.message)

        typeof  userAccountInfo.userlogin !== 'undefined' &&  setUserLogin(userAccountInfo.userlogin)
        typeof  userAccountInfo.username !== 'undefined' &&  setUserName(userAccountInfo.username)
        typeof  userAccountInfo.userrole !== 'undefined' &&  setUserRole(userAccountInfo.userrole)

    }catch (err){
        console.log(err)
    }

You are doing setUserAccountInfo and then you are expecting in next line that you will access that new state by inspecting typeof userAccountInfo..., and you will not, because state update is async and you will access new state only after rerender(in next function call) - state is being accessed from closure which recreates on each rerender.

Rewrite to this:

try{
        const response = await axios.post(
            backendUrl   'user' , requestData
        )
        
        const accountInfo = response?.data?.message;
        setUserAccountInfo(accountInfo)
        

        typeof  accountInfo.userlogin !== 'undefined' && setUserLogin(accountInfo.userlogin)
        typeof  accountInfo.username !== 'undefined' &&  setUserName(accountInfo.username)
        typeof  accountInfo.userrole !== 'undefined' &&  setUserRole(accountInfo.userrole)

    }catch (err){
        console.log(err)
    }

You need to preserve value you are passing into setUserAccountInfo and then use that value(and not the current state) to do some additional checks and state updates.

  • Related