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

140
Views
State not updating from useEffect hook

For some reason when I am updating my state from the useEffect hook it is not persisting. I am expecting that my list of users will keep growing, but instead I am only seeing one user. Why is users not growing?

import { useState, useEffect } from "react";

interface IUser {
  name: {
    first: string;
    last: string;
  };
  picture: {
    thumbnail: string;
  };
}

function App() {
  const [users, setUsers] = useState<IUser[]>([]);

  const getUserName = (user: IUser): string => {
    if (!user) return "";

    return `${user.name.first} ${user.name.last}`;
  };

  const getThumbnail = (user: IUser): string => {
    if (!user) return "";

    return user.picture.thumbnail;
  };

  useEffect(() => {
    setInterval(() => {
      fetch("https://randomuser.me/api")
        .then((res) => res.json())
        .then((json) => {
          let newusers = [...users, json.results[0]];
          setUsers(newusers);
        })
        .catch((err) => {
          console.log(err);
        });
    }, 3000);
  }, []);

  return (
    <div className="App">
      {users?.map((user, idx) => (
        <div key={idx}>
          <h2>{getUserName(user)}</h2>
          <img src={getThumbnail(user)} />
        </div>
      ))}
    </div>
  );
}

export default App;

Here is a codesandbox demonstrating the issue https://codesandbox.io/s/react-typescript-forked-5h3553?file=/src/App.tsx:0-1054

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

0

The problem comes from the use of setInterval. When it is defined, it creates a closure including the current value of the variable users which of course starts as []. So every time the interval is invoked, it is using the value it had at the time of instantiation.

Luckily, calls to setState pass a parameter of the previous state, which you can use to quickly fix your problem:

.then((json) => {
  setUsers((prev) => [...prev, json.results[0]]);
})
about 4 years ago · Juan Pablo Isaza Report

0

You need to use the method returned from useState hook to update the array.

Here is the solution:

let newuser = json.results[0];
setUsers(prev => [...prev, newuser]);

Instead of:

let newusers = [...users, json.results[0]];
setUsers(newusers);
about 4 years ago · Juan Pablo Isaza Report

0

Just update setUsers directly like this:

setUsers(prevState => […prevState, json.results[0]]);
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!