Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

174
Vistas
Setting state in React useEffect hook

In my app I fetch data from my API after a button is clicked that changes the state of endpoint. Until the data is fetched I want to display a loading icon. After MUCH testing, I finally got it to work. This is what it looks like:

  const [endpoint, setEndpoint] = useState('products');
  const [loading, setLoading] = useState(true);
  const [data, setData] = useState([]);

  useEffect(() => {
    setLoading(true);

    fetch(`/api/${endpoint}`, {
      method: 'GET',
    })
    .then(res => res.json())
    .then(data => {
      setData(data);
    })
    .catch(e => {
      setData([]);
    })
    .finally(() => setLoading(false));

  }, [endpoint]);

  const onSelect = (option) => {
    setEndpoint(option);
  }

  return (
    <>
      <Sidebar onSelect={onSelect}/>
      <div className="main">
        <Banner />
        {loading ? 'Loading...' : JSON.stringify(data)}
      </div>
    </>
  );

Even though I get the result that I want, I'm a bit confused as to how it all fits together because I'm new to React. Please correct me If I'm wrong, but this is my understanding:

setEndpoint triggers a re-render, which causes useEffect to execute because it has a dependency on endpoint. Each set state call inside useEffect also causes a re-render. For instance when setLoading(true) is called, the screen is re-rendered to show 'Loading...'. Once the state of loading is set to true, fetch gets called. As soon as the promise is resolved, setData(data) causes another re-render. However, my data isn't displayed on screen until setLoading(false) is called, re-rendering the screen yet again, displaying my data. So in total, the screen is re-rendered 3 times (right?).

I'm still confused because I was under the impression that hooks like useEffect are asynchronous so why would it wait for the state to be set before continuing to execute the next lines of code?

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

The useEffect hook callback is completely synchronous. What you are seeing is the asynchronous Promise chain at work.

useEffect(() => {
  setLoading(true); // (3)

  fetch(`/api/${endpoint}`, { // (4)
    method: 'GET',
  })
    .then(res => res.json())
    .then(data => {
      setData(data); // (6)
    })
    .catch(e => {
      setData([]); // (6)
    })
    .finally(() => setLoading(false)); // (7)
}, [endpoint]); // (2)

const onSelect = (option) => {
  setEndpoint(option); // (1)
}

...

{loading ? 'Loading...' : JSON.stringify(data)} // (5), (8)

What you explain as your understanding is largely correct.

  1. An endpoint state update is enqueued the callback function completes and the state updates is processed, triggering a rerender.
  2. The useEffect hook is called, its dependencies checked. Since endpoint value updated, the useEffect callback is invoked.
  3. A loading state update is enqueued. The callback function is still running.
  4. A fetch request is made. fetch returns a Promise, and the code starts a Promise chain. This chain is asynchronous. The useEffect hook callback now completes and since there is no more synchronous code to run. The loading state update is processed and a rerender is triggered.
  5. The UI conditionally renders the loading indicator.
  6. Here the Promise chain has either resolved or rejected, a data state update is enqueued and a Promise returned in the chain. The data state update is processed and a rerender triggered.
  7. The end of the Promise chain, a loading state update is enqueued. The loading state is processed and a rerender is triggered.
  8. The UI now conditionally renders the data.

So in total, the screen is re-rendered 3 times (right?).

By my count the logic above likely triggered 4 rerenders, but React could have potentially rerendered any number of times for just about any other reason. React components rerender when either state or props update, or the parent component rerenders.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda