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

272
Vistas
React 18, useEffect is getting called two times on mount

I have a counter and set console.log in useEffect to log every change in my state, but the useEffect is getting called twice on mount. I'am using React v18.0.0. Here is a CodeSandbox of my project and the code below:

import  { useState, useEffect } from "react";

const Counter = () => {
  const [count, setCount] = useState(5);

  useEffect(() => {
    console.log("rendered");
    console.log(count);
  }, [count]);

  console.log("rendered");

  return (
    <div>
      <h1> Counter </h1>
      <div> {count} </div>
      <button onClick={() => setCount(count + 1)}> click to increase </button>
    </div>
  );
};

export default Counter;
about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

This behaviour is from React 18 itself when you are in strict mode in development. The core team is trying to implement this feature where we can preserve components' state even after unmount. useEffect getting called twice is related to this feature. Here is an overview of what they say in the documentation:

In the future, we’d like to add a feature that allows React to add and remove sections of the UI while preserving state.

With Strict Mode starting in React 18, whenever a component mounts in development, React will simulate immediately unmounting and remounting the component.

On the second mount, React will restore the state from the first mount. This feature simulates user behavior such as a user tabbing away from a screen and back, ensuring that code will properly handle state restoration.

This only applies to development mode, production behavior is unchanged.

However if you need to, for example in your case where you want the useEffect's callback to execute only when a state changes, you can use a boolean ref using useRef to add some additional controls, like so:

import  { useState, useEffect, useRef } from "react";

const Counter = () => {
  const firstRenderRef = useRef(true);
  const [count, setCount] = useState(5);

  useEffect(() => {
    if(firstRenderRef.current){
      firstRenderRef.current = false;
      return;
    }
    console.log("rendered", count);
  }, [count]);

  return (
    <div>
      <h1> Counter </h1>
      <div> {count} </div>
      <button onClick={() => setCount( count + 1 )}> click to increase </button>
    </div>
  );
};

export default Counter;
about 4 years ago · Juan Pablo Isaza Denunciar

0

For add more information to yousoumar's answer, React team wrote a post about useEffect where explain this and how use this hook correctly:

Synchronizing with Effects

about 4 years ago · Juan Pablo Isaza Denunciar

0

Use a ref or make a custom hook without one.

import type { DependencyList, EffectCallback } from 'react';
import { useEffect } from 'react';

const useClassicEffect = import.meta.env.PROD
  ? useEffect
  : (effect: EffectCallback, deps?: DependencyList) => {
      useEffect(() => {
        let subscribed = true;
        let unsub: void | (() => void);

        queueMicrotask(() => {
          if (subscribed) {
            unsub = effect();
          }
        });

        return () => {
          subscribed = false;
          unsub?.();
        };
      }, deps);
    };

export default useClassicEffect;
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