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

311
Views
'if else statement' doesn't work properly when importing data as props in React

if else statement inside useEffect doesn't work as expected. else is executed before the code inside the if is executed completely. I've commented out what I'm expecting in the code. someData prop is the data fetched from the server using the fetch API in the parent component.

import { useState, useEffect } from "react";

const App = ({ someData }) => {
  const [text, setText] = useState(0)
  const [lastNumber, setLastNumber] = useState(0)
  useEffect(() => {
    if (!someData) {
      (async () => {
        const res = await fetch(`https://xxx-xxx......`);
        const myJson = await res.json();
        const _lastNumber = myJson.number // 1000
        setLastNumber(_lastNumber)
        console.log(lastNumber) // 1000, appear in the console second
      })();
    } else {
        console.log(lastNumber) // 0, appear in the console first
        setText(
          lastNumber - someData.number // 0 - 100 (I expect "1000 - 100".)
        );
    }
  }, [someData, lastNumber]);

  if (!someData) {
    return (
      <div>
        <h1>Loading</h1>
      </div>
    )
  } else {
    return (
      <div>
        <h1>{text /* -100 (I expect "900".) */}</h1>
      </div>
    );
  }
};

export default App;

If I write code like this using some tricks, it takes a long time to load but works as I want.

import { useState, useEffect } from "react";

const App = ({ someData }) => {
  const [text, setText] = useState(0)
  const [lastNumber, setLastNumber] = useState(0)
  useEffect(() => {
    if (!someData) {
      (async () => {
        const res = await fetch(`https://xxx-xxx......`);
        const myJson = await res.json();
        const _lastNumber = myJson.number // 1000
        setLastNumber(_lastNumber)
        console.log(lastNumber)
      })();
    } else {
      if (lastNumber !== 0) {
        console.log(lastNumber) 
        setText(
          lastNumber - someData.number
        );
      }
    }
  }, [someData, lastNumber]);

  if (!someData) {
    return (
      <div>
        <h1>Loading</h1>
      </div>
    )
  } else {
    return (
      <div>
        <h1>{text /* 900 */}</h1>
      </div>
    );
  }
};

export default App;

But I don't know why it works the way that I want and if it's a good way to do it. Please let me know the better way.

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

0

You need to move effect in dedicated async function, in order to await part of the execution. In your current solution your effect is synchronous and IIFE you declared will be executed synchronously thus can cause unexpected behaviour of effect.

Rewrite to this(in order to await code execution):

 const doSomething = async () => {
   if (!someData) {
      const res = await fetch(`https://xxx-xxx......`); // NOW YOU CODE WILL WAIT
      const myJson = await res.json();
      const _lastNumber = myJson.number; // 1000
      setLastNumber(_lastNumber);
      console.log(lastNumber); // YOU CAN NOT EXPECT TO READ NEW VALUE IMMEDIATELY, THIS WILL LOG OLD VALUE FOR lastNumber
    } else {
      console.log(lastNumber); // 0, appear in the console first
      setText(
      lastNumber - someData.number // 0 - 100 (I expect "1000 - 100".)
      );
    }
  };

 useEffect(() => {
   doSomething();

 }, [someData, lastNumber]);

Also, in console.log(lastNumber) part you can not expect to log latest value, one that was set in line before, because state update is async and state is accessed from closure meaning you will access new value from lastNumber but only after rerender.

about 4 years ago · Juan Pablo Isaza Report

0

Yeah! Async functions... )) Read this article for explanations.

The issue here is that the first argument of useEffect is supposed to be a function that returns either nothing (undefined) or a function (to clean up side effects). But an async function returns a Promise, which can't be called as a function! It's simply not what the useEffect hook expects for its first argument.

enum LoadingStatusEnum {
    INACTIVE = -1,
    ACTIVE = 1,
    ERROR = 0,
}

export default function Example({someData}): JSX.Element {
    const [text, setText] = useState(0);
    const [lastNumber, setLastNumber] = useState(0);
    const [loadingStatus, setLoadingStatus] = useState<LoadingStatusEnum>(LoadingStatusEnum.INACTIVE);
    useEffect(() => {
        const fetchData = async () => {
            setLoadingStatus(LoadingStatusEnum.ACTIVE);
            const response = await fetch('API action here');
            const json = await response.json();
            setLastNumber(json.number);
        };

        if (!someData && loadingStatus !== LoadingStatusEnum.ACTIVE) {
            fetchData()
                .then(() => {
                    setLoadingStatus(LoadingStatusEnum.INACTIVE);
                })
                .catch(() => {
                    setLoadingStatus(LoadingStatusEnum.ERROR);
                });
        } else {
            setText(lastNumber - someData.number);
        }
    }, [someData, lastNumber]);

    const renderTitle = () => {
        let title = String(text);
        if (loadingStatus === LoadingStatusEnum.ACTIVE) {
            title = 'Loading';
        }
        if (loadingStatus === LoadingStatusEnum.ERROR) {
            title = 'Error';
        }

        return title;
    };

    return (
        <div>
            <h1>
                {renderTitle()}
            </h1>
        </div>
    );
}

 
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!