具有以下代码,我希望在更改价格和数量的值时,在父组件中修改产品的状态,这部分起作用,因为更新信息存在延迟,因此我必须将值写两倍价格和数量可以看到一些结果。更改状态变量的值时出现这种延迟的原因是什么?
import React, { useState } from "react";
const initialState = [
{
id: 1,
name: "Nintendo switch",
price: 250,
quantity: 0,
subTotal: 0
},
{
id: 2,
name: "Nintendo 3DS",
price: 199,
quantity: 0,
subTotal: 0
},
{
id: 3,
name: "playstation 4",
price: 300,
quantity: 0,
subTotal: 0
}
];
function Totals({ products }) {
function getTotal(key) {
return products.reduce((previousValue, currentValue) => {
return (previousValue += currentValue[key]);
}, 0);
}
return (
<tr>
<td />
<td>{getTotal("price")}</td>
<td>{getTotal("quantity")}</td>
<td>{getTotal("subTotal")}</td>
</tr>
);
}
function Product({ product, onChange }) {
const [price, setPrice] = useState(product.price);
const [quantity, setQuantity] = useState(product.quantity);
function onChangePrice(event) {
setPrice(event.target.value);
onChange({ id: product.id, price, quantity });
}
function onChangeQuantity(event) {
setQuantity(event.target.value);
onChange({ id: product.id, price, quantity });
}
return (
<tr>
<td>{product.name}</td>
<td>
<input onChange={onChangePrice} value={price} />
</td>
<td>
<input onChange={onChangeQuantity} value={quantity} />
</td>
<td>{product.subTotal}</td>
</tr>
);
}
function App() {
const [products, setProducts] = useState(initialState);
function onChangeHandler(entry) {
const output = products.map(product =>
product.id === entry.id
? {
...product,
price: +entry.price,
quantity: +entry.quantity,
subTotal: +entry.price * +entry.quantity
}
: product
);
setProducts(output);
}
return (
<table>
<thead>
<tr>
<th>Name</th>
<th>Price</th>
<th>Quantity</th>
<th>Sub total</th>
</tr>
</thead>
<tbody>
{products.map(product => (
<Product
key={product.id}
product={product}
onChange={onChangeHandler}
/>
))}
<Totals products={products} />
</tbody>
</table>
);
}
export default App;
请看一下这个例子
答案 0 :(得分:2)
问题在于,您实际上是将状态存储在2个地方,而它们并不总是一致的。 Product
组件应该是无状态的,因为您要保持产品列表中的状态。
function Product({ product, onChange }) {
function onChangePrice(e) {
onChange({ id: product.id, price: e.target.value, quantity: product.quantity });
}
function onChangeQuantity(e) {
onChange({ id: product.id, quantity: e.target.value, price: product.price });
}
return (
<tr>
<td>{product.name}</td>
<td>
<input onChange={onChangePrice} value={product.price} />
</td>
<td>
<input onChange={onChangeQuantity} value={product.quantity} />
</td>
<td>{product.subTotal}</td>
</tr>
);
}
答案 1 :(得分:1)
尽管Product
的 local price
和quantity
的设置正确,但是您正在呼叫onChange
,这是道具由父组件向下传递,并带有 old 值:
function onChangePrice(event) {
setPrice(event.target.value);
onChange({ id: product.id, price, quantity });
}
function onChangeQuantity(event) {
setQuantity(event.target.value);
onChange({ id: product.id, price, quantity });
}
如果出于某种原因您确实需要在子组件和父组件中存储价格和数量,请确保使用onChange
而不是 old来调用event.target.value
在price
和quantity
中的值:
function onChangePrice(event) {
setPrice(event.target.value);
onChange({ id: product.id, price: event.target.value, quantity });
}
function onChangeQuantity(event) {
setQuantity(event.target.value);
onChange({ id: product.id, price, quantity: event.target.value });
}