慣性聚合 高效追讀感興趣之博客、新聞、科技資訊
閱原文 以慣性聚合開啟

推薦訂閱源

aimingoo的专栏
aimingoo的专栏
宝玉的分享
宝玉的分享
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
WordPress大学
WordPress大学
V
V2EX
Apple Machine Learning Research
Apple Machine Learning Research
J
Java Code Geeks
腾讯CDC
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Engineering at Meta
Engineering at Meta
L
LangChain Blog
Jina AI
Jina AI
博客园 - 叶小钗
B
Blog RSS Feed
Recent Announcements
Recent Announcements
H
Help Net Security
小众软件
小众软件
大猫的无限游戏
大猫的无限游戏
B
Blog
云风的 BLOG
云风的 BLOG
Blog — PlanetScale
Blog — PlanetScale
D
DataBreaches.Net
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
罗磊的独立博客

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Cómo solucionar el bucle infinito en `useEffect` con obje...
Erick Eduard · 2026-05-24 · via DEV Community

Erick Eduardo Ramos

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

Explicación técnica

El problema ocurre porque useEffect compara las dependencias usando comparación por referencia (===), no por contenido. 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) y vuelve a ejecutar el efecto, causando el bucle infinito.

En tu caso:

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

useEffect(() => {
  setIngredients({}); // ← ¡Crea un nuevo objeto!
}, [ingredients]); // ← Siempre es una referencia diferente → bucle infinito

Enter fullscreen mode Exit fullscreen mode

Solución definitiva (3 enfoques)

Opción 1: Usar estado funcional + comparación profunda (recomendada)

useEffect(() => {
  setIngredients(prev => {
    // Solo actualiza si el contenido realmente cambió
    if (Object.keys(prev).length > 0) {
      return {};
    }
    return prev;
  });
}, []); // ← Sin dependencias: solo ejecuta al montar

Enter fullscreen mode Exit fullscreen mode

Opción 2: Comparar contenido manualmente con useDeepCompareEffect

// Implementa una comparación profunda personalizada
function useDeepCompareEffect(callback, dependencies) {
  useEffect(() => {
    callback();
  }, [dependencies.map(dep => JSON.stringify(dep))]);
}

// Uso:
useDeepCompareEffect(() => {
  setIngredients({});
}, [ingredients]);

Enter fullscreen mode Exit fullscreen mode

Opción 3: Usar useReducer para lógica compleja (mejor práctica)

const initialState = {};
function reducer(state, action) {
  switch (action.type) {
    case 'reset':
      return {};
    default:
      return state;
  }
}

const [ingredients, dispatch] = useReducer(reducer, initialState);

useEffect(() => {
  dispatch({ type: 'reset' });
}, []); // ← Sin dependencias

Enter fullscreen mode Exit fullscreen mode

Bloque de código corregido (recomendado)

import { useState, useEffect } from 'react';

function MyComponent() {
  const [ingredients, setIngredients] = useState({});

  useEffect(() => {
    // Solo resetea si el objeto no está vacío
    setIngredients(prev => 
      Object.keys(prev).length > 0 ? {} : prev
    );
  }, []); // ← Sin dependencias para evitar bucles

  return (
    <div>
      <p>Ingredients: {JSON.stringify(ingredients)}</p>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

Pro-tip: Regla de oro para objetos y arrays en useEffect

Nunca incluyas objetos/arrays directamente en las dependencias si vas a crear nuevos objetos/arrays dentro del efecto.

En su lugar:

  • Usa [] si la lógica solo necesita ejecutarse al montar/desmontar
  • Usa comparación profunda para dependencias dinámicas
  • Considera useReducer para estados complejos
  • Para validaciones simples, compara propiedades específicas (ej: ingredients.length en lugar del array completo)