React状态没有正确更新.增加和减少功能不工作的第一次点击,但工作后,随后的点击



React状态未正确更新。增加和减少功能不工作的第一次点击,但工作后,随后的点击。小计价值总是错的。如果数量为10,小计应为105。但小计显示为94.50

import React from "react";
import { Card, Button, CardDeck } from 'react-bootstrap';
import { useState } from "react";
import image from "../images/image.PNG";
import "./productcard.css";
function ProductCard() {
const price = Number(10.50);
const [quantity, setQuantity] = useState(0);
const [subtotal, setSubtotal] = useState(0);
function calculatesubtotal() {
const sub = quantity * price;
setSubtotal(sub);
}
function increase() {
setQuantity(quantity+ 1 );     
calculatesubtotal();   
}
function decrease(e) {
setQuantity(quantity- 1);
calculatesubtotal();
e.stopPropagation();
}
return (
<Card className="card" onClick={increase}>
<Card.Img className="image" variant="top" src={image} />
<Card.Body className="body">
<Card.Title className="title">White Bread 700g</Card.Title>
</Card.Body>
<label className="quantity-label">QTY</label>
<div className="quantity-area">
<Button className="increase-button" variant="primary" onClick={increase}>+</Button>
<input className="quantity" type="number" value={quantity}/>
<Button className="decrease-button" variant="primary" onClick={decrease}>-</Button>
</div>
<label className="price-label" >Price</label>
<input className="price" type="number" value={price} />  
<label className="subtotal-label" >Subtotal</label>
<input className="subtotal" type="number" value={subtotal}/>


</Card>
);
}
export default ProductCard;
function increase() {
setQuantity(quantity+ 1 );     
calculatesubtotal();   
}

因为这里当您更新quantity时,calculatesubtotal内部的quantity读取仍然指向旧值。您可以将新值传递给calculatesubtotal并在内部使用。

function increase() {
let newQt = quantity+ 1 ;
setQuantity(newQt);     
calculatesubtotal(newQt); // Modify calculatesubtotal accordingly
}

当您的值直接依赖于另一个状态值时,最好不要在状态时复制它,而只是在每次状态值更改时执行计算:

const price = Number(10.50);
const [quantity, setQuantity] = useState(0);
function increase() {
setQuantity(quantity+ 1 );     
}
function decrease(e) {
setQuantity(quantity- 1);
e.stopPropagation();
}
const subtotal = useMemo(() => quantity * price,[quantity])

更少的代码和声明式的方法。

使用useEffect钩子代替下面的calculatessubtotal函数

import React,{useEffect} from "react";
...
uesEffect(()=>{
setSubtotal(quantity * price);
},[quantity]]
import React,{useEffect} from "react";
import { Card, Button, CardDeck } from 'react-bootstrap';
import { useState } from "react";
import image from "../images/image.PNG";
import "./productcard.css";
function ProductCard() {
const price = Number(10.50);
const [quantity, setQuantity] = useState(0);
const [subtotal, setSubtotal] = useState(0);
uesEffect(()=>{
setSubtotal(quantity * price);
},[quantity]]
function increase() {
setQuantity(quantity+ 1 );     
}
function decrease(e) {
setQuantity(quantity- 1);
e.stopPropagation();
}
return (
<Card className="card" onClick={increase}>
<Card.Img className="image" variant="top" src={image} />
<Card.Body className="body">
<Card.Title className="title">White Bread 700g</Card.Title>
</Card.Body>
<label className="quantity-label">QTY</label>
<div className="quantity-area">
<Button className="increase-button" variant="primary" onClick={increase}>+</Button>
<input className="quantity" type="number" value={quantity}/>
<Button className="decrease-button" variant="primary" onClick={decrease}>-</Button>
</div>
<label className="price-label" >Price</label>
<input className="price" type="number" value={price} />  
<label className="subtotal-label" >Subtotal</label>
<input className="subtotal" type="number" value={subtotal}/>


</Card>
);
}
export default ProductCard;

解释

每当数量发生变化时,这个useEffect将被调用并根据最新的数量更新小计

最新更新