Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

181
Visualizações
React async data fetch in useEffect

I'm trying to load data through an asynchronous method in useEffect. I pass all the necessary dependencies and, in my understanding, useEffect should work when the component is mounted, on the first render, and when dependencies change.

useEffect(() => { 
        console.log('effect')
        if (ids.length === 0) {
            api.images.all().then((data) => { console.log(data); setIDs(data) }).catch(console.log)
        }
    }, [ids])

In my case it's 3 times: mount (it should load data immediately), first render (shouldn't go into if), and due to ids change (should also not go into if). But useEffect fires 4 times and loads data twice, I can't figure out why.

enter image description here

Component code:

//BuildIn
import { useEffect, useState } from 'react'
//Inside
import api from '../services/api.service'
import AsyncImage from '../components/AsyncImage.component'

const ImagesPage = () => {
    const [ids, setIDs] = useState([])

    useEffect(() => { 
        console.log('effect')
        if (ids.length === 0) {
            api.images.all().then((data) => { console.log(data); setIDs(data) }).catch(console.log)
        }
    }, [ids])

    return(
        <>
            {(ids.length > 0) ? ids.map((id, index) => <AsyncImage guid={id} key={index} />) : <div>No data</div>}
        </>
    )
}

export default ImagesPage
about 4 years ago · Santiago Gelvez
2 Respostas
Responde à pergunta

0

I've re-implemented the business logic of your example and it works well. The only thing you have to fix is to pass the setIDs to the useEffect as a dependency. The component renders twice which is fine; the first one is the initial render and the second one occurs when the data is present.

You can even get rid of the if condition. Simply do not pass the id to the useEffect hook and it will fetch the images on mount only.

// import { useState, useEffect } from 'react' --> with babel import
const { useState, useEffect } = React  // --> with inline script tag

const api = {
  images: { all: () => new Promise(res => res(['id1', 'id2'])) }
}

const ImagesPage = () => {
    const [ids, setIDs] = useState([])

    useEffect(() => { 
      api.images.all()
      .then(data => {
        setIDs(data)
      })
      .catch(console.log)
    }, [setIDs])

    return(
      <ul>
        {console.log('reders')}
        {ids.map(id => <li key={id}>{id}</li>)}
      </ul>
    )
}

ReactDOM.render(<ImagesPage />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.9.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>

about 4 years ago · Santiago Gelvez Relatório

0

try to do this :

useEffect(() => {
    async function fetchData() {
      const res = await loadMovies();
      setIDs(res)
    }
    fetchData();
  }, []);
about 4 years ago · Santiago Gelvez Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda