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

180
Visualizações
React state updates only when component is re-rendered

I'm trying to increment value of React state setMoviesPage by 1 each time handleScroll() is called. The issue I'm facing is that the state setMoviesPage is updated only the component is re-rendered (by navigating to a different url and coming back).

This is my code:

  const [moviesPage, setMoviesPage] = useState(1);


  async function handleScroll() {
    if (window.innerHeight + document.documentElement.scrollTop !== document.documentElement.offsetHeight) return;
    await setIsFetching(true);
    setMoviesPage(moviesPage + 1);
  }

  useEffect(() => {
    if (!isFetching) return;
    fetchMovies(String(moviesPage))
    .then(prevState => updateMovies([...prevState]))
    .catch(() => updateMovies([]));
    
    setIsFetching(false);   
  }, [isFetching, setIsFetching, moviesPage, updateMovies]);

How to fix it? Thanks

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

When first looked up your code, what I really want to tell you is your useEffect seems not on best practice used.

Here I modify it for you with better structure.

const fetchMovie = () => {
   setIsFetching(true)
   fetchMovies(String(moviesPage))
    .then(prevState => updateMovies([...prevState]))
    .catch(() => updateMovies([]));
   setIsFetching(false)
}

useEffect(() => {
   fetchMovie
}, [moviesPage]);

And please note that you only need add the dependencies array to useEffect all the value changed that will trigger your action inside it. Also sometimes linter can give you some false positive warning.

Hope this answer can help you solve your problem.

about 4 years ago · Juan Pablo Isaza Relatório

0

Issue

It seems that when fetching movies is complete you simply overwrite the existing state.

fetchMovies(String(moviesPage))
  .then(prevState => updateMovies([...prevState])) // <-- overwrite state
  .catch(() => updateMovies([]));

With function components and the useState hook, state updates are not merged in with existing state, you must manage this manually.

Note

Unlike the setState method found in class components, useState does not automatically merge update objects. You can replicate this behavior by combining the function updater form with object spread syntax:

const [state, setState] = useState({});
setState(prevState => {
  // Object.assign would also work
  return {...prevState, ...updatedValues};
});

Solution

Update the moviesPage value in the scroll handler

function handleScroll() {
  if (window.innerHeight + document.documentElement.scrollTop !== document.documentElement.offsetHeight) return;
  setMoviesPage(moviesPage + 1);
}

Factor out the fetching logic into a utility function. Use a functional state update to update from the previous state, appending the new data to a new array reference. Move the resetting of the loading state into the Promise chain so it's correctly reset at the end of the chain, otherwise it would just cancel out the starting loading true update.

const fetchNextMoviesPage = (page) => {
  if (!isFetching) {
    setIsFetching(true); // <-- start loading
    fetchMovies(String(page))
      .then(nextPage => {
        updateMovies(movies => movies.concat(nextPage)); // <-- append next page
      })
      .catch(() => updateMovies([]))
      .finally(() => setIsFetching(false)); // <-- end loading
  }
};

useEffect(() => {
  fetchNextMoviesPage(moviesPage); 
}, [moviesPage]);
about 4 years ago · Juan Pablo Isaza 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