惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
H
Help Net Security
N
Netflix TechBlog - Medium
Apple Machine Learning Research
Apple Machine Learning Research
P
Proofpoint News Feed
A
About on SuperTechFans
V
V2EX
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
宝玉的分享
宝玉的分享
aimingoo的专栏
aimingoo的专栏
F
Fortinet All Blogs
博客园 - 【当耐特】
Microsoft Security Blog
Microsoft Security Blog
Martin Fowler
Martin Fowler
I
InfoQ
Google DeepMind News
Google DeepMind News
人人都是产品经理
人人都是产品经理
Engineering at Meta
Engineering at Meta
腾讯CDC
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
B
Blog RSS Feed
U
Unit 42
The Cloudflare Blog
Y
Y Combinator Blog

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 objeto...
Erick Eduard · 2026-05-23 · 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 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:

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

Enter fullscreen mode Exit fullscreen mode


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:

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

Enter fullscreen mode Exit fullscreen mode

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):

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

Enter fullscreen mode Exit fullscreen mode

⚠️ 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):

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

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

Enter fullscreen mode Exit fullscreen mode

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

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

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

Enter fullscreen mode Exit fullscreen mode


Bloque de código corregido (recomendado)

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

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

Enter fullscreen mode Exit fullscreen mode


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

Enter fullscreen mode Exit fullscreen mode