Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

249
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda