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

147
Vistas
Bucle infinito en useEffect

He estado jugando con el nuevo sistema de enlace en React 16.7-alpha y me quedo atascado en un bucle infinito en useEffect cuando el estado que estoy manejando es un objeto o una matriz.

Primero, uso useState y lo inicio con un objeto vacío como este:

 const [obj, setObj] = useState({});

Luego, en useEffect, uso setObj para configurarlo como un objeto vacío nuevamente. Como segundo argumento, estoy pasando [obj], con la esperanza de que no se actualice si el contenido del objeto no ha cambiado. Pero sigue actualizándose. Supongo que porque no importa el contenido, estos siempre son objetos diferentes que hacen que React piense que sigue cambiando.

 useEffect(() => { setIngredients({}); }, [ingredients]);

Lo mismo ocurre con los arreglos, pero como primitivo no se atascará en un bucle, como se esperaba.

Usando estos nuevos ganchos, ¿cómo debo manejar los objetos y la matriz al verificar si el contenido ha cambiado o no?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Pasar una matriz vacía como segundo argumento a useEffect hace que solo se ejecute en el montaje y desmontaje, deteniendo así cualquier bucle infinito.

 useEffect(() => { setIngredients({}); }, []);

Esto se me aclaró en la publicación del blog sobre React hooks en https://www.robinwieruch.de/react-hooks/

over 4 years ago · Santiago Trujillo Denunciar

0

Tenía el mismo problema. No sé por qué no mencionan esto en los documentos. Solo quiero agregar un poco a la respuesta de Tobias Haugen.

Para ejecutar en cada renderizado principal/componente , debe usar:

 useEffect(() => { // don't know where it can be used :/ })

Para ejecutar cualquier cosa solo una vez después del montaje del componente (se procesará una vez), debe usar:

 useEffect(() => { // do anything only one time if you pass empty array [] // keep in mind, that component will be rendered one time (with default values) before we get here }, [] )

Para ejecutar cualquier cosa una vez en el montaje del componente y en el cambio de datos/datos2 :

 const [data, setData] = useState(false) const [data2, setData2] = useState('default value for first render') useEffect(() => { // if you pass some variable, than component will rerender after component mount one time and second time if this(in my case data or data2) is changed // if your data is object and you want to trigger this when property of object changed, clone object like this let clone = JSON.parse(JSON.stringify(data)), change it clone.prop = 2 and setData(clone). // if you do like this 'data.prop=2' without cloning useEffect will not be triggered, because link to data object in momory doesn't changed, even if object changed (as i understand this) }, [data, data2] )

Cómo lo uso la mayor parte del tiempo:

 export default function Book({id}) { const [book, bookSet] = useState(false) const loadBookFromServer = useCallback(async () => { let response = await fetch('api/book/' + id) response = await response.json() bookSet(response) }, [id]) // every time id changed, new book will be loaded useEffect(() => { loadBookFromServer() }, [loadBookFromServer]) // useEffect will run once and when id changes if (!book) return false //first render, when useEffect did't triggered yet we will return false return <div>{JSON.stringify(book)}</div> }
over 4 years ago · Santiago Trujillo Denunciar

0

También me encontré con el mismo problema una vez y lo solucioné asegurándome de pasar valores primitivos en el segundo argumento [] .

Si pasa un objeto, React almacenará solo la referencia al objeto y ejecutará el efecto cuando la referencia cambie, lo que suele ser cada vez (aunque no sé cómo).

La solución es pasar los valores en el objeto. Puedes probar,

 const obj = { keyA: 'a', keyB: 'b' } useEffect(() => { // do something }, [Object.values(obj)]);

o

 const obj = { keyA: 'a', keyB: 'b' } useEffect(() => { // do something }, [obj.keyA, obj.keyB]);
over 4 years ago · Santiago Trujillo 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