originally I was gonna ask how to call a function inside a map but I realize I wasn't doing anything wrong in the way I was calling my function so I just think that my code is wrong.
So I'm trying to do a summation of all the prices of a map i'm rendering sometimes those prices change due to the quantity that the person might want so I was calling:
//My function call inside the map
{calculateTotal(fixedPrice)}
//The function
const calculateTotal = (price) => {
setTotalPrice (totalPrice + price)
}
But I got this error in return

I don't understand how adding 2 numbers certain amount of times (in this case 9) would end up in an infinite loop. All I want to do is to sum all the prices into one variable and if the cantidad/quantity changes it add those changes too.

whole code in case you need it
import React, { useState, useEffect } from 'react'
import { auth, db } from './firebase';
import { useHistory } from 'react-router-dom';
import { Checkbox } from '@material-ui/core';
function CrearPedidos({user}) {
const [libros, setLibros] = useState([]);
const [cantidad, setCantidad] = useState( new Array(libros.length).fill(1));
useEffect(()=>{
setCantidad(new Array(libros.length).fill(1))
}, [libros])
const history = useHistory("");
const [totalPrice, setTotalPrice] = useState();
const librosRef = db.collection('libros');
const queryRef = librosRef.where('grado', '==', '4° Grado');
useEffect(() => {
queryRef.orderBy("precio")
.get()
.then((snapshot) => {
const tempData = [];
snapshot.forEach((doc) => {
const data = doc.data();
tempData.push(data);
});
setLibros(tempData);
});
}, []);
const mas = (index) => {
setCantidad(cantidad[index]++);
setCantidad([...cantidad])
};
const menos = (index) => {
if (cantidad[index] > 0){
setCantidad(cantidad[index]--);
setCantidad([...cantidad])
}
else {
window.alert("Sorry, Zero limit reached");
}
};
const calculateTotal = (price) => {
setTotalPrice (totalPrice + price)
}
return (
<div className="listado_Pedidos">
<div className="estudiantes_container">
<h1 className = "estudiantes_container_h1">Estudiante: {user.displayName}</h1>
<h1 className = "estudiantes_container_h1">Libros Nuevos</h1>
<div className ="tableContainer">
<table>
<thead>
<tr className="Lista">
<th>Cantidad</th>
<th>Grado</th>
<th>Descripcion</th>
<th>Editorial</th>
<th>Precio</th>
</tr>
</thead>
<tbody>
{libros.map((libros, index, fixedPrice) => (
<tr key={libros.id || index}>
<td>
<button onClick = {() => mas(index)}/>
{cantidad[index]}
{console.log(cantidad)}
<button onClick = {() => menos(index)}/>
</td>
<td>{libros.grado}</td>
<td >
<input onChange = {(event) => {
let checked = event.target.checked;
}}
type="checkbox" checked = "">
</input>
{libros.descripcion}
</td>
<td >{libros.editorial}</td>
<td >${fixedPrice = parseFloat(libros.precio).toFixed(2) * cantidad[index]}</td>
{calculateTotal(fixedPrice)}
</tr>
))
}
</tbody>
</table>
</div>
<div className="space" />
<button onClick="{realizarPedidos}" className = "crear_estudiante_boton">Realizar Pedidos</button>
<div className="space" />
</div>
</div>
)
}
export default CrearPedidos
It's about two theoretical points.
You must notice that map returns an array of values. So if you call a function, it will be call multiple times.
In React, when state changes, component will re-render on every change. In map you call a function that changes state. Then state changing re-render all component. Again the map call that function , again and again. And this is an infinity loop.
If you want count total price, must do it outside of map return.
Separate logic. Do all countings outside of component return. Then in component return just show jsx elements
As @Danial said, you're updating state so many times, very fastly, which triggers page renderization, and throw the error you got.
To do this summation of all items into the array, use reduce array function instead of map.
Reference: How to find the sum of an array of numbers
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With