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

497
Views
Why does this React's useEffect() fires twice after loaded?

I have this very simple component called Editor:

export default function Editor() {
  const [error, setError] = useState(null);
  const [isLoaded, setIsLoaded] = useState(false);
  const [currentData, setCurrentData] = useState({});

  useEffect(() => {
    fetch("http://localhost:4000/pages")
      .then(res => res.json())
      .then(
        (result) => {
          setIsLoaded(true);
          setCurrentData(result);
        },
        (error) => {
          setIsLoaded(true);
          setError(error);
        }
      )
  }, [])

  if (error) {
    return (
      <LoadingError value={error.message} />
    );
  } else if (!isLoaded) {
    return (
      <Loading />
    )
  } else {
    console.log(currentData);
  }

  return ( <div></div> );
}

Notice the last else condition, where my currentData is logged into the console.

What happens when this component is rendered is that my console.log() fires twice! The first time my currentData object is empty. The second time, the object properly contains all the data from my API.

However, as my console.log() should fire only when there is no error (the first if condition), and only when the data is loaded (the second else if condition), how is it possible that I end up with empty object in the console the first time? What am I doing wrong?

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

0

Your useEffect only fires once. You're seeing the console.log output twice because you're doing updateState twice. Change the order to see the expected behaviour you're looking for

This is what's happening right now:

setIsLoaded(true); // Causes 1st rerender and so console.log executes with []
setCurrentData(result); // Causes second rerender and console.log has data.

What you want:

setCurrentData(result); // Causes 1st rerender but does not reach the else statement
setIsLoaded(true); // Reaches the else statement and currentData is already set

This will make sure your currentData is set before isLoaded is set to true

As of now, React does not batch update state calls in the above scenario, but this will change once React v18 is released.

about 4 years ago · Juan Pablo Isaza Report

0

Why does this React's useEffect() fires twice after loaded?

It doesn't.

The function Editor runs again because you call setIsLoaded and setCurrentData once the promise in the effect (which runs only once) resolves.

about 4 years ago · Juan Pablo Isaza Report

0

I have a feeling that React only batches state updates for certain handlers, like onClick and others, but I have feeling that when state updates occur in the callback of a promise, they dont get batched, so you will have two renders happening in your case.

edit - which is probably what @Harkunwar's answer is alluding to, in that the order in which you update your state matters

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!