# Cómo solucionar el bucle infinito en useEffect con objetos y arrays

> Source: <https://dev.to/erickeduardoramos03/como-solucionar-el-bucle-infinito-en-useeffect-con-objetos-y-arrays-52oa>
> Published: 2026-05-23 10:23:54+00:00

# Cómo solucionar el bucle infinito en useEffect con objetos y arrays

## Explicación técnica

El problema ocurre porque `useEffect`

compara los valores de las dependencias usando **comparación de referencia ( ===)**, no por contenido (deep equality). Cuando usas

`useState({})`

, cada llamada a `setObj({})`

crea un **nuevo objeto en memoria**, aunque tenga el mismo contenido. React detecta que la referencia cambia (

`obj !== obj`

), lo que dispara la reejecución del `useEffect`

, causando el bucle infinito.En tu caso:

``` js
const [ingredients, setIngredients] = useState({});
useEffect(() => {
  setIngredients({}); // ¡Crea un nuevo objeto!
}, [ingredients]); // ingredients cambia de referencia → reejecuta → loop infinito
```

## Pasos para solucionarlo

### Opción 1: Evitar la actualización innecesaria (recomendada)

Si no necesitas actualizar el estado dentro del `useEffect`

, **elimina la dependencia del objeto/array** y usa un array vacío:

``` js
useEffect(() => {
  // Solo ejecutar al montar el componente
  setIngredients({});
}, []); // ✅ Sin dependencias → solo se ejecuta una vez
```

### Opción 2: Comparación profunda manual

Si necesitas ejecutar el `useEffect`

solo cuando el *contenido* cambia, usa `JSON.stringify`

(para objetos simples sin funciones/circularidades):

``` js
useEffect(() => {
  setIngredients({});
}, [JSON.stringify(ingredients)]); // ✅ Compara contenido, no referencia
```

⚠️ **Advertencia**: `JSON.stringify`

es costoso en objetos grandes y falla con funciones, `undefined`

, o referencias circulares.

### Opción 3: Usar `useMemo`

para una representación estable

Crea una representación estable del objeto (ej. número de elementos, hash):

``` js
const ingredientsHash = useMemo(() => 
  Object.keys(ingredients).length, // o tu lógica personalizada
  [ingredients]
);

useEffect(() => {
  setIngredients({});
}, [ingredientsHash]); // ✅ Compara valor primitivo estable
```

### Opción 4: Validar si el valor es distinto antes de actualizar

Evita la actualización si el contenido es idéntico:

``` js
useEffect(() => {
  if (Object.keys(ingredients).length > 0) {
    setIngredients({});
  }
}, [ingredients]); // ✅ Solo actualiza si no está vacío
```

## Bloque de código corregido (recomendado)

``` js
const [ingredients, setIngredients] = useState({});

useEffect(() => {
  // Solo ejecutar al montar el componente (ej. limpiar estado inicial)
  setIngredients({});
}, []); // ✅ Solución definitiva para este caso
```

## Pro-tip

-
**Nunca actualices el mismo estado que usas como dependencia** sin una lógica de comparación profunda. - Para objetos complejos, usa librerías como
`immer`

o`useDeepCompareEffect`

(de`use-deep-compare-effect`

) si necesitas comparación profunda segura. - Si el objetivo es limpiar el estado al montar, usa
`useEffect`

con`[]`

y no actualices el estado dentro. En su lugar, inicializa el estado con el valor deseado desde el inicio:

```
const [ingredients, setIngredients] = useState({}); // ✅ Inicialización directa
```


