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

253
Visualizações
useEffect calling api's couple of times reactjs

I have this useEffect function in react component. I am calling api videoGridState here. Now what is happening here it is calling my api 2 times one at intitial page reaload and second one when count is changing. I want it to be called single time when page reloads. But also when streamSearchText changes

  const [count, setCount] = useState(0);
  const [streamSearchText, setStreamSearchText] = useState("");
  useEffect(() => {
    videoGridState();
  }, [count]);

  useEffect(() => {
    const delayDebounceFn = setTimeout(() => {
      setCount(count + 1);
    }, 1000);

    return () => clearTimeout(delayDebounceFn);
  }, [streamSearchText]);

How can I do that?

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

0

The main issue is that you have two useEffect calls, and so they're each handled, and the second triggers the first (after a delay), resulting in the duplication.

As I understand it, your goal is:

  1. Run videoGridState immediately on mount, and
  2. Run it again after a delay of 1000ms whenever streamSearchText changes

That turns out to be surprisingly awkward to do. I'd probably end up using a ref for it:

const firstRef = useRef(true);
const [streamSearchText, setStreamSearchText] = useState("");
useEffect(() => {
    if (firstRef.current) {
        // Mount
        videoGridState();
        firstRef.current = false;
    } else {
        // `streamSearchText` change
        const timer = setTimeout(() => {
            videoGridState();
        }, 1000);
        return () => clearTimeout(timer);
    }
}, [streamSearchText]);

Live Example:

const { useState, useRef, useEffect } = React;

function videoGridState() {
    console.log("videoGridState ran");
}

const Example = () => {
    const firstRef = useRef(true);
    const [streamSearchText, setStreamSearchText] = useState("");
    useEffect(() => {
        if (firstRef.current) {
            // Mount
            videoGridState();
            firstRef.current = false;
        } else {
            // `streamSearchText` change
            const timer = setTimeout(() => {
                videoGridState();
            }, 1000);
            return () => clearTimeout(timer);
        }
    }, [streamSearchText]);

    return <div>
        <label>
            Search text:{" "}
            <input
                type="text"
                value={streamSearchText}
                onChange={(e) => setStreamSearchText(e.currentTarget.value)}
            />
        </label>
    </div>;
};

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Example />);
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>

You could also do the query immediately when streamSearchText is "", but that would happen every time streamSearchText was "", not just on mount. That may be good enough, depending on how rigorous you need to be.


Additionally, though, if you're still seeing something happen "on mount" twice, you may be running a development copy of the libraries with React.StrictMode around your app (the default in many scaffolding systems). See this question's answers for details on how React.StrictMode may mount your component more than once and throw in other seeming surprises.

about 4 years ago · Juan Pablo Isaza Relatório

0

Your following useEffect() function makes this behaviour to happen:

  useEffect(() => {
    const delayDebounceFn = setTimeout(() => {
      setCount(count + 1);
    }, 1000);

    return () => clearTimeout(delayDebounceFn);
  }, [streamSearchText]);

Since it runs initially but called setCount() which updates the state, and forces a re-render of the component which in turn runs the first useEffect() since that has [count] in the dependency array.

And hence the cycle continues for the [count]

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