Tengo un estado que debe actualizarse cada vez que cambia otro estado. Así que usé el efecto usado con el elemento de matriz de dependencia de otro estado, pero está causando un renderizado infinito. Quiero usar estas variables como estados. Quiero que totalAmount sea una variable de estado para la cual se necesitan otras variables para ser estado (subtotal de descuento, etc.). Cuál podría ser la solución a esto.
Aplicación.js
import { useState, useEffect } from 'react'; import './styles.css'; function App() { let order = [ { qty: 2, name: 'Margarita A', variant: 'crab & cucumber', price: '412.00', } ]; let [discount, setDiscount] = useState(759.5), [deliveryFee, setDeliveryFee] = useState(12.0), [taxes, setTaxes] = useState(46.15), [subtotal, setSubtotal] = useState(0), [totalAmount, setTotalAmount] = useState(0); useEffect(() => { setTotalAmount(subtotal - discount + deliveryFee + taxes); }, [subtotal, discount, deliveryFee, taxes]); return ( <div className="app"> <div className="container"> <div className="orderItems"> {order.map((item, i) => { // subtotal += +item.price; setSubtotal((prev) => prev + +item.price); return ( <div className="orderItem" key={i}> <span className="orderItemPrice">₹{item.price}</span> </div> ); })} </div> </div> <div className="summary"> <span className="summaryTitle">Summary</span> <div className="total amountBox"> <span>Total</span> <span>₹ {totalAmount}</span> </div> </div> </div> <div className="placeOrder"> <button onClick={(e, totalAmount) => {}}>PLACE ORDER</button> </div> </div> ); } export default App; el problema no está en su gancho useEffect , está funcionando correctamente y se llamó una vez cuando el componente se montó. el problema es con setSubtotal((prev) => prev + +item.price); en su método de return .
Cada cambio en las variables de estado provocará una nueva representación, con cada nueva representación se volverá a crear su order.map . por lo tanto, cambiar el estado durante order.map hará que se vuelva a renderizar y la nueva renderización hará que order.map se dibuje nuevamente. Es la causa de tu renderizado infinito.
Nota: simplemente puede comentar setState dentro de su función de map para detener este comportamiento.
Hay algunas opciones para controlar esta situación, como usar useRef para subtotal para evitar la causa de volver a renderizar.
Además, puede calcular su subtotal dentro de su useEffect antes del cálculo de totalAmount y configurarlo.
function App() { let order = [ { qty: 2, name: "Margarita A", variant: "crab & cucumber", price: "412.00" } ]; const [discount, setDiscount] = useState(59.5); const [deliveryFee, setDeliveryFee] = useState(12.0); const [taxes, setTaxes] = useState(46.15); const [subtotal, setSubtotal] = useState(0); const [totalAmount, setTotalAmount] = useState(0); useEffect(() => { const localSubtotal = order.reduce( (acc, curr) => (acc += Number(curr.price)), 0 ); setSubtotal(localSubtotal); setTotalAmount(localSubtotal - discount + deliveryFee + taxes); }, [discount, deliveryFee, taxes, order]); return ( <div className="app"> <div className="container"> <div className="orderItems"> {order.map((item, i) => { return ( <div className="orderItem" key={i}> <span className="orderItemPrice">₹{item.price}</span> </div> ); })} </div> </div> <div> <div className="summary"> <div> <span>Sub Total: {subtotal}</span> </div> <span className="summaryTitle">Summary</span> <div className="total amountBox"> <span>Total</span> <span>₹ {totalAmount}</span> </div> </div> </div> <div className="placeOrder"> <button onClick={(e, totalAmount) => {}}>PLACE ORDER</button> </div> </div> ); } export default App; Nota: no olvide pasar la matriz de order en la matriz de dependencia en el gancho useEffect .