REACT JS - 如何在地图内进行求和?
REACT JS - How to do a summation inside a map?
最初我想问一下如何在地图中调用一个函数,但我意识到我调用函数的方式并没有做错任何事情,所以我只是认为我的代码是错误的。
所以我正在尝试对我正在渲染的地图的所有价格进行汇总,有时这些价格会因人们可能想要的数量而发生变化,所以我打电话给:
//My function call inside the map
{calculateTotal(fixedPrice)}
//The function
const calculateTotal = (price) => {
setTotalPrice (totalPrice + price)
}
但是我在 return
中遇到了这个错误
我不明白如何将 2 个数字相加一定次数(在本例中为 9)会导致无限循环。我想要做的就是将所有价格汇总到一个变量中,如果 cantidad/quantity 发生变化,它也会添加这些变化。
完整代码以备不时之需
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
大概是两个理论点。
您必须注意到 map
return 是一个值数组。所以如果你调用一个函数,它会被调用多次。
在 React 中,当状态改变时,组件将在每次改变时重新渲染。在 map
中,你调用了一个改变状态的函数。然后状态改变重新渲染所有组件。 map
一次又一次地调用该函数。这是一个无限循环。
如果你想计算总价,必须在地图外进行return。
分离逻辑。在组件 return
之外进行所有计数。然后在组件 return 中只显示 jsx elements
正如@Danial 所说,您更新状态很多次,非常快,这会触发页面呈现,并抛出您遇到的错误。
要对数组中的所有项目求和,请使用 reduce
数组函数而不是映射。
参考:How to find the sum of an array of numbers
嗨,我只是在尝试之后才弄明白(无法正确理解 reduce)这是另一种不使用 reduce 而只使用 useEffect
的方法
const [libros, setLibros] = useState([]);
const [cantidad, setCantidad] = useState( new Array(libros.length).fill(1));
const [totalPrice, setTotalPrice] = useState([]);
useEffect((i) => {
let x = 0
libros.map((i, index) => {
x += i.precio * cantidad[index]
setTotalPrice(parseFloat(x).toFixed(2))
})
})
... some code
//And then just call the variable
<h1>Precio total: {totalPrice}</h1>
这是它的样子!
它也会在每次“cantidad”上升或下降时更新!
删除这些行:
const [cantidad, setCantidad] = useState(...);
const [totalPrice, setTotalPrice] = useState();
改为使用 useMemo
钩子。
const cantidad = useMemo(() => {
return new Array(libros.length).fill(1);
}, [libros]);
const total = useMemo(() => {
return libros.reduce((sum, libro, index) => {
return sum + parseFloat(libro.precio) * cantidad[index];
}, 0);
}, [cantidad, libros]);
然后像这样使用它:
<td>{total.tofixed(2)}</td>
最初我想问一下如何在地图中调用一个函数,但我意识到我调用函数的方式并没有做错任何事情,所以我只是认为我的代码是错误的。
所以我正在尝试对我正在渲染的地图的所有价格进行汇总,有时这些价格会因人们可能想要的数量而发生变化,所以我打电话给:
//My function call inside the map
{calculateTotal(fixedPrice)}
//The function
const calculateTotal = (price) => {
setTotalPrice (totalPrice + price)
}
但是我在 return
中遇到了这个错误我不明白如何将 2 个数字相加一定次数(在本例中为 9)会导致无限循环。我想要做的就是将所有价格汇总到一个变量中,如果 cantidad/quantity 发生变化,它也会添加这些变化。
完整代码以备不时之需
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
大概是两个理论点。
您必须注意到
map
return 是一个值数组。所以如果你调用一个函数,它会被调用多次。在 React 中,当状态改变时,组件将在每次改变时重新渲染。在
map
中,你调用了一个改变状态的函数。然后状态改变重新渲染所有组件。map
一次又一次地调用该函数。这是一个无限循环。
如果你想计算总价,必须在地图外进行return。
分离逻辑。在组件 return
之外进行所有计数。然后在组件 return 中只显示 jsx elements
正如@Danial 所说,您更新状态很多次,非常快,这会触发页面呈现,并抛出您遇到的错误。
要对数组中的所有项目求和,请使用 reduce
数组函数而不是映射。
参考:How to find the sum of an array of numbers
嗨,我只是在尝试之后才弄明白(无法正确理解 reduce)这是另一种不使用 reduce 而只使用 useEffect
的方法const [libros, setLibros] = useState([]);
const [cantidad, setCantidad] = useState( new Array(libros.length).fill(1));
const [totalPrice, setTotalPrice] = useState([]);
useEffect((i) => {
let x = 0
libros.map((i, index) => {
x += i.precio * cantidad[index]
setTotalPrice(parseFloat(x).toFixed(2))
})
})
... some code
//And then just call the variable
<h1>Precio total: {totalPrice}</h1>
这是它的样子!
它也会在每次“cantidad”上升或下降时更新!
删除这些行:
const [cantidad, setCantidad] = useState(...);
const [totalPrice, setTotalPrice] = useState();
改为使用 useMemo
钩子。
const cantidad = useMemo(() => {
return new Array(libros.length).fill(1);
}, [libros]);
const total = useMemo(() => {
return libros.reduce((sum, libro, index) => {
return sum + parseFloat(libro.precio) * cantidad[index];
}, 0);
}, [cantidad, libros]);
然后像这样使用它:
<td>{total.tofixed(2)}</td>