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

118
Visualizações
UseEffect is thrown when it shouldn't be

I use a useEffect in my React code which works fine at first but writing a search engine using a useState called "search" when setting its new value through an input onChange my useEffect is executed automatically again although it is never waiting changing my useState to "search", this is my code

const [search, setSearch] = useState("");

useEffect(() => {
  pages();
}, [limitPage, page, products]);

const pages = () => {
  // eslint-disable-next-line
  getProducts(limitPage, page, search);
  getXlsProducts(100000, 1);
  const totalPages = Math.ceil(totalDocs / limitPage);
  const links = [];
  for (let i = 1; i <= totalPages; i++) {
    links[i] = i;
  }
  setNumbers(links);

  setTotalDocs(products.products?.totalDocs);
  setTotalPages(products.products?.totalPages);
  setCurrentPage(products.products?.page);
  setNextPage(products.products?.hasNextPage);
  setPreviousPage(products.products?.hasPrevPage);
};

I need to use the button that calls the handleSearch() function in order to perform the search, but as soon as a change in the input automatically occurs, my useEffect is executed:

<div>
  <input
    className="border-1 border-2 border-solid rounded border-slate-300"
    value={search}
    onChange={(e) => setSearch(e.target.value)}
  />
  <button onClick={() => handleSearch()}>
    <FiSearch />
  </button>
</div>

Here is the function to use when clicking on the button but it is never used because as soon as search changes value through the input it no longer gets executed:

const handleSearch = () => {
  setLimitPage(10);
  setPage(1);
  getProducts(limitPage, page, search);
};

How can I avoid the automatic firing of my useEffect so that I can use my search function through the button? thanks.

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

0

useEffect(() => {
  pages();
}, [limitPage, page, products]);

Dependencies in React's hooks use shallow comparison.

As @ChrisG mentioned in the comment - "You have infinite loop". It's async loop because as you said, getProducts function request products from the server. So when you get a list of products from the server even if they semantically equal as already setted you still create a new array with new reference. So useEffect triggered again because reference on products list has changed!

//🥇triggered useEffect by first run
// when we create component and call `pages()`
useEffect(() => {
  pages();
}, [limitPage, page, products]);


const pages = () => {
  //🥈Make a request to the server and set products list
  // like setProducts(response.products) this cause
  // create new array with new reference
  getProducts(limitPage, page, search);
  ...
}

//🥉products === response.products // False because these are two diffirent objects
// so we trigger useEffect again (returns to 🥈)
useEffect(() => {
  pages();
}, [limitPage, page, products]);
about 4 years ago · Juan Pablo Isaza Relatório

0

As far as I have understood , you want getProducts() to be called on the first render as well as whenever the state limitPage and page changes and whenever Search Button is pressed.

You already have handleSearch function for calling getProducts() that is triggering the API on the click of Search button,

const handleSearch = () => {
  setLimitPage(10);
  setPage(1);
   getProducts(limitPage, page, search);
};

In the handleSearch() as mentioned by @ChrisG in comment :- you need to take care of limitPage and page value as it will use the previous value here.

for calling API on first render and whenever the states limitPage and pagechanges, remove products dependency from useEffect and modify pages() function with the required statements:-

useEffect(() => {
   pages();
 }, [limitPage, page]);

const pages = () => {
  // eslint-disable-next-line
  getProducts(limitPage, page, search);
  getXlsProducts(100000, 1);
  const totalPages = Math.ceil(totalDocs / limitPage);
  const links = [];
  for (let i = 1; i <= totalPages; i++) {
  links[i] = i;
 }
  setNumbers(links);

};

I saw several states that you want to update on the change of products state, for that , you can have another useEffect with products dependency and a new method updating the required states:-

 useEffect(() => {
   updateStates();
 }, [products]);

const updateStates = () => {
  setTotalDocs(products.products?.totalDocs);
  setTotalPages(products.products?.totalPages);
  setCurrentPage(products.products?.page);
  setNextPage(products.products?.hasNextPage);
  setPreviousPage(products.products?.hasPrevPage);
 };
 
about 4 years ago · Juan Pablo Isaza Relatório

0

The problem is the shallow comparison as stated by @maksimr. An alternative is to use class based components with shouldComponentUpdate:

shouldComponentUpdate(nextProps, nextState) {
    // if no products in current state, update when there are products in 
    // future state, or else remain.
    if(!this.state.products.length) {
        return nextState.products.length;
    }
    // update if there's a product in current state whose id
    // is not found in the next state's products
    return this.state.products.some((prod)=>(
        !nextState.products.find((p)=> (
            prod.id == p.id 
        )
    );
}
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