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

107
Visualizações
Prevent infinite loop on function component with default parameter and useEffect

When creating a function component in React and setting a default parameter everything works like expected and the component will be rendered once. But as soon as you add a hook like useEffect and use this parameter in the dependency array the component rerenders forever. I've created a simple demo here: https://codesandbox.io/s/infinite-useeffect-loop-on-default-value-tv7hj?file=/src/TestComponent.jsx

The reason is quite obvious, because when using an object as default parameter, it will be created again and will not be equal to the previous one. And of course this doesn't happen on primitive default parameter values like number or string.

Is there any better way to avoid this side effect besides using defaultProps?

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

0

Yes, instead of setting the default value of value to being an object, just set it to false. Then check if value is truthy, if it is, then access the correct properties, otherwise, just show a default value. New code.

It would be something like:

import { useEffect, useState } from "react";

const TestComponent = ({ value = false }) => {
  const [calcValue, setCalcValue] = useState(0);

  useEffect(() => {
    setCalcValue((cur) => cur + 1);
  }, [value]);

  return (
    <div>
      {value ? value.name : "Test"}:{calcValue}
    </div>
  );
};
about 4 years ago · Juan Pablo Isaza Relatório

0

The reason you get infinite loops is because the reference of value keeps changing.

The first time the component is rendered, it sees a new reference to value, which triggers the useEffect, which in turns modifies the state of the component, and this leads to a new render, which causes value to be re-created once again because the old reference to that variable has changed.

The easiest way to deal with this is to just create a default value outside the component and use that (basically the same as the defaultProps solution):

import { useEffect, useState } from "react";

const defaultValue = {name: "Test"}; // <-- default here
const TestComponent = ({ value = defaultValue }) => {
  const [calcValue, setCalcValue] = useState(0);

  useEffect(() => {
    setCalcValue((cur) => cur + 1);
  }, [value]);

  return (
    <div>
      {value.name}:{calcValue}
    </div>
  );
};

Doing this will ensure that each time the component renders, it sees the same reference for value, therefore the useEffect hook only runs once.


Another way of dealing with this is to first wrap your component with memo, then create a new state variable which takes on the original value, and make your useEffect hook depend on this new state variable:

const TestComponent = React.memo(({ value = {name: "Test"} }) => {
  const [calcValue, setCalcValue] = useState(0);
  const [myValue, setMyValue] = useState(value);

  useEffect(() => {
    setCalcValue((cur) => cur + 1);
  }, [myValue]);

  return (
    <div>
      {myValue.name}:{calcValue}
    </div>
  );
});

The reason why we wrap the component with memo is so that it only re-renders after a state change if the prop had changed in value (instead of reference). You can change the way memo detects props changes by providing a custom comparison function as a second parameter.

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