0

I'm making an api call inside useEffect to fetch user data then trying to update the user state but the problem is, the user state stick to null even tho I successfully got the user from the axios call

here is my code :

AuthContext.js :

import { createContext , useState ,useEffect } from 'react'
import axios from 'axios'

export const AuthContext = createContext()

const AuthState = ({children}) => {

    const [user , setUser] = useState(null)

    useEffect(() => {

    const fetchUser = async () => {
      try {
        const res = await axios.get('http://localhost:8000/auth/user' , { withCredentials : true })
        console.log ('user in response => ' , res.data)

        setUser(res.data)

        console.log ('user in state => ' , user)
        } catch(err) {
        console.log('There was a problem')
         }
     }
       fetchUser()

    },[])

    return (

     <AuthContext.Provider value={user}>{children}</AuthContext.Provider>

           )
     }

export default AuthState

index.js :

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import AuthState from './AuthContext'

ReactDOM.render(
  <React.StrictMode>
    <AuthState>
    <App />
    </AuthState>
  </React.StrictMode>,
  document.getElementById('root')
);

console output (img) : console output

Why setUser does not update the user state?

  • the `setter` of the state is async so it will be updated in the next render. If you add `useEffect(()=>console.log( user ), [user]);` you will see that it gets logged. – Gabriele Petrioli Dec 31 '21 at 22:20
  • @GabrielePetrioli oh thank you , so the user of the state is logged before the res is fetched .. omg I realized the answer was obvious but never mind I'm a beginner lol – CodeLearner Dec 31 '21 at 23:27
  • no not before it is fetched. But it is logged before the variable has been re-assigned. – Gabriele Petrioli Dec 31 '21 at 23:36
  • @GabrielePetrioli isn't it because the api call takes some time to get the response so the program log the user in state first (when it still null) and then when we get the response from the api call user in state gets updated? .. but in the console the user from api call is logged before the user from the state , this is confusing .. thank you I will dive deeper into this subject – CodeLearner Dec 31 '21 at 23:49
  • No, the `fetchUser` method `await` for the fetch to complete, so the log that is in the same code block after the `await` will run after the fetch is complete. Bit the `setUser` method itself, is async which means that it will not immediately update the value. Read [useState set method not reflecting change immediately](https://stackoverflow.com/questions/54069253/usestate-set-method-not-reflecting-change-immediately) for more in-depth explanation – Gabriele Petrioli Jan 01 '22 at 08:54

1 Answers1

0

Here the user data is actually updating properly.

Having console.log('user in state => ' , user) // is not proper way to test. This gives null because rerender did not happen in useEffect. To have a rerender affect useeffect you need to add user in dependency array [user].

but you dont need any change in code as this is working properly. For testing this I recommend add these in index.js.

  ReactDOM.render(
      <React.StrictMode>
        <AuthState>
        <AuthContext.Consumer> // <--To test
        {(user) => <div>{user && user.id}</div>} // <--To test
        </AuthContext.Consumer> // <--To test
        <App />
        </AuthState>
      </React.StrictMode>,
      document.getElementById('root')
    );
Rahul Kishan
  • 314
  • 4
  • 18