Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

88
Views
React useEffect updating with default initialized useState

I'm trying to create an array state variable called usersInfos that I can append to whenever I do an api call, but useEffect is updating with the initial value of the userData state variable.

// api.js
import axios from 'axios';

export function fetchUserData () {
    return axios.get('https://randomuser.me/api')
    .then(res => {
        return res;
    })
    .catch(err => {
        console.error(err);
    })
}
import { fetchUserData } from '../../src/api';
import { useState, useEffect } from 'react';
import ProfileCard from './profilecard';

export default function UserProfile() {
    const [userData, setUserData] = useState();
    const [usersInfos, setUsersInfos] = useState([]);

    const getUserData = async () => {
        let ud = await fetchUserData()
        setUserData(ud);
    }

    useEffect(() => {
        getUserData();
    }, [])

    useEffect(() => {
        const newInfos =  [
            ...usersInfos,
            userData,
        ]
        setUsersInfos(newInfos);
        console.log(usersInfos);
    }, [userData])

    return (
        <div className='userprofile'>
            <button onClick={() => { getUserData() }}> Fetch Random User </button>

            <button onClick={() => { console.log(usersInfos) }}> log usersInfos </button>

            {usersInfos.map((user, idx) => {
                <ProfileCard userData={user} key={idx} />
            })}
        </div>
    )

}

I'm assuming it's something to do with the state batch updating, but I'm not sure. What would be the best practice way of doing this? I am console logging with the button at the bottom, after the page has loaded.

When userData is initialized to (), I get console log: (2) [undefined, {…}]

When userData is initialized to (0), I get console log: (2) [0, {…}].

When userData is initialized to ([]), i get console log:(2) [Array(0), {…}]

Thanks

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

When the 2nd effect runs for the first time, userData is undefined because the network request isn't resolved yet. You could simply run the effect only when userData is not undefined.

useEffect(() => {
  if (userData) {
    const newInfos =  [
      ...usersInfos,
      userData,
    ]
    setUsersInfos(newInfos);
  }
}, [userData])

However, if the code presented in the question is almost complete, I would use the code below instead. In this way I can update both states with a single effect.

The code below is a snippet from the CodeSandbox fully functional example.

export default function UserProfile() {
  const [userData, setUserData] = useState();
  const [usersInfos, setUsersInfos] = useState([]);

  const getUserData = useCallback(async () => {
    let ud = await fetchUserData();
    setUserData(ud);
    setUsersInfos((prevInfos) => [...prevInfos, ud]);
  }, []);

  useEffect(() => {
    getUserData();
  }, [getUserData]);


  return (
    <div className="userprofile">
      <button onClick={getUserData}>Fetch Random User</button>

      <button
        onClick={() => {
          console.log(usersInfos);
        }}
      >
        log usersInfos
      </button>
      {userData && (
        <p>
          Current user: {userData.name.first} {userData.name.last}
        </p>
      )}
      <ul>
        {usersInfos.map((user, idx) => (
          <ProfileCard userData={user} key={idx} />
        ))}
      </ul>
    </div>
  );
}

If you try to log userInfos just after the setter, it will log the previous state because the function inside the effect is a closure and it captures the value of the state when the effect runs. Since React state is immutable the state update does not works like an assignment but it will be updated at the next render.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!