He pasado dos días tratando de averiguar qué está pasando y todavía no puedo averiguar dónde está el problema. Es muy frustrante :((
Tengo este código en la caja de arena de código que obtiene de una API el mes y el total y luego hago cálculos simples.
https://codesandbox.io/s/agitated-cdn-q3gju?file=/src/Card.js
El primer problema: con cada actualización de la página, el valor en la pantalla primero representará el primer total y luego, en la segunda actualización, generará el segundo total. (consulte el código en sandbox para comprender mejor lo que quiero decir)
El segundo problema: cuando trato de consola. registrar los revenue , obtengo la matriz impresa en la consola dos veces, no estoy seguro de por qué la obtiene dos veces.
El tercer problema: entiendo que podría tener algo que ver con mi código de back-end (que incluyo un fragmento a continuación), pero realmente he revisado cada línea para depurar y no puedo detectar el error.
Su ayuda es muy apreciada 🙏
router.get("/incomestats", verifyTokenAndAdmin, async (req, res) => { const date = new Date(); const lastMonth = new Date(date.setMonth(date.getMonth() - 1)); const previousMonth = new Date(date.setMonth(lastMonth.getMonth() - 1)); // const previousMonth = new Date(new Date().setMonth(lastMonth.getMonth() - 1)); try { const ordersData = await Order.aggregate([ { $match: { createdAt: { $gte: previousMonth } } }, { $project: { month: { $month: "$createdAt" }, sales: "$amount" } }, { $group: { _id: "$month", total: { $sum: "$sales" } } }, ]); res.status(200).json(ordersData); } catch (error) { res.status(500).json(error); console.log(error); } });El problema principal es con la matriz de dependencia que pasó a su llamada useEffect .
useEffect(() => { const getRevenue = async () => { try { const res = ...; setRevenue(res.data); setDifference((res.data[1].total * 100) / (res.data[0].total - 100)); } catch (error) { ... } }; getRevenue(); }, [difference]); Tienes [difference] cuando debería ser [setRevenue, setDifference] . Al incluir la difference , le está diciendo a reaccionar que necesita ejecutar este efecto cuando la diferencia cambia SIN EMBARGO, también está llamando a setDifference aquí, que cambia el valor de la difference . Esto se repetirá infinitamente. Cambiar las dependencias a [setRevenue, setDifference] resolverá el problema del bucle infinito.
useEffect(() => { const getRevenue = async () => { try { const res = ...; setRevenue(res.data); setDifference((res.data[1].total * 100) / (res.data[0].total - 100)); } catch (error) { ... } }; getRevenue(); }, [setRevenue, setDifference]); La segunda cosa (que discutiblemente ni siquiera es un problema) es que dentro useEffect está llamando a setRevenue y setDifference en un contexto asíncrono. En las versiones de React anteriores a la nueva versión beta (18), React no procesa por lotes estas dos actualizaciones de estado. Esta pregunta lo explica muy bien en mi opinión.