重新渲染太多.React 限制渲染的数量以防止无限循环.更新呈现方法内功能组件的状态



每次显示购物车商品时,我都想使用 render 方法中的 useState 函数更新商品的总价格和数量。但是,在呈现 UI 后,我立即收到上面提到的反应错误。

有没有更好的方法来做我想要实现的目标而不会出错?

const Cart = () => {
const cartItems = useItems()
const firebase = useFirebase()
//Items count
//Total amount of the items
let [total, updateTotal] = useState(0)
let [count, updateCount] = useState(1)
//Method to add items to the cart
useEffect(() => {
if (!firebase) return
}, [firebase, cartItems])


return (
<Layout>
<SEO title="Cart" />
<Navbar count={count} />
<MDBContainer>
<MDBCol lg="12" className="">
<MDBTable responsive className="mt-5 z-depth-1">
<MDBTableHead>
<tr className="bg-light">
<th>
<div className="p-1 px-3 text-uppercase font-weight-bold">
Product
</div>
</th>
<th>
<div className="p-1 px-3 text-uppercase font-weight-bold">
Price
</div>
</th>
<th>
<div className="p-1 px-3 text-uppercase font-weight-bold">
Quantity
</div>
</th>
<th>
<div className="p-1 px-3 text-uppercase font-weight-bold">
Remove
</div>
</th>
</tr>
</MDBTableHead>
<MDBTableBody id="products-list">
{cartItems.map(product => {
updateTotal((total += product.price))
updateCount((count += 1))
return (
<tr>
<td class="px-3 font-weight-normal">
{product.name} <span class="d-none">{product.id}</span>{" "}
</td>
<td width="10%" class="text-center font-weight-normal">
{product.price}
<span>/kg </span>{" "}
</td>
<td width="10%" class="text-center font-weight-normal">
{product.count}
</td>
<td width="10%" class="text-center">
<div class="px-3 font-weight-normal">
{" "}
<button
class="bg-transparent border-0"
id="delete-button"
>
<i class="fa fa-trash-alt delete-icon"></i>
</button>
</div>
</td>
</tr>
)
})}
</MDBTableBody>
<MDBTableFoot>
<tr>
<td className="px-3 text-uppercase font-weight-bold">Total</td>
<td className="font-weight-bold px-5">&#8377;{total}</td>
<td className="font-weight-bold pr-2 text-center">{count}</td>
</tr>
</MDBTableFoot>
</MDBTable>
</MDBCol>
</MDBContainer>
</Layout>
)
}
export default Cart

使用空白[]而不是[firebase, cartItems]

下面的代码应该适合你:

const cartItems = useItems();
// I assume this gives you cartItems.
let [total, updateTotal] = useState(() => {
if (cartItems) {
// item object {id: "2", name: "Cucumber", category: "vegetable", price: 50, // //count: 0}
return cartItems.reduce((acc, elem) => {
acc += elem.price * elem.count;
return acc;
}, 0);
}
return 0;
});
let [count, updateCount] = useState(cartItems.length);
React.useEffect(() => {
if (cartItems) {
updateCount(cartItems.length);
// item object {id: "2", name: "Cucumber", category: "vegetable", price: 50, // //count: 0}
const total = cartItems.reduce((acc, elem) => {
acc += elem.price * elem.count;
return acc;
}, 0);
updateTotal(total);
}
}, [cartItems]);

因此,基本上,一旦从useItems获得一些值,就需要启动状态,然后在cartItems引用更改时也需要更新它

放置 [firebase, cartItems] 告诉 react 如果对这两个参数进行任何更改,则始终重新渲染。所以这就是为什么有太多的重新渲染。

最新更新