Javascript 无法正确更新状态中的总值
我正在编写没有redux的简单购物车系统 预期行为:更改产品数量时更新总量 问题:Javascript 无法正确更新状态中的总值,javascript,reactjs,react-dom,Javascript,Reactjs,React Dom,我正在编写没有redux的简单购物车系统 预期行为:更改产品数量时更新总量 问题: 首次渲染后,总金额为0 删除项目后,总金额不变 我需要:优雅的解决方案。不是硬代码 const产品=[ { id:“1”, 标题:“项目1”, 价格:“2450”, 左:“14”, 数量:“1” }, { id:“2”, 标题:“项目2”, 价格:“2450”, 左:“178”, 数量:“1” }, { id:“3”, 标题:“项目3”, 价格:“2450”, 左:“1”, 数量:“1” }, { id:“4”
0
const产品=[
{
id:“1”,
标题:“项目1”,
价格:“2450”,
左:“14”,
数量:“1”
},
{
id:“2”,
标题:“项目2”,
价格:“2450”,
左:“178”,
数量:“1”
},
{
id:“3”,
标题:“项目3”,
价格:“2450”,
左:“1”,
数量:“1”
},
{
id:“4”,
标题:“项目4”,
价格:“2450”,
左:“12”,
数量:“1”
}
];
类应用程序扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
产品:这个。道具。产品,
购物车:这个。道具。产品,
总数:0
};
this.handleRemoveProduct=this.handleRemoveProduct.bind(this);
this.handleChangeQuantity=this.handleChangeQuantity.bind(this);
this.sumTotalAmount=this.sumTotalAmount.bind(this);
}
HandlerRemoveProduct(id){
让购物车=this.state.cart;
购物车=购物车。过滤器((产品)=>{
return product.id!=id;
} );
此.setState({
运货马车
} );
这个.sumTotalAmount();
}
HandleChange数量(e,id){
让购物车=this.state.cart;
购物车=购物车.地图((产品)=>{
if(product.id==id){
product.quantity=e.target.value;
}
退货产品;
} );
此.setState({
运货马车
} );
这个.sumTotalAmount();
}
sumTotalAmount(){
让购物车=this.state.cart;
让totalAmount=cart.map((产品)=>{
退货编号(产品数量)*编号(产品价格);
})。减少((总,电流)=>总+=电流);
此.setState({
总数
} );
}
render(){
返回(
{
this.state.cart.map((项目,索引)=>{
返回(
)
})
}
总额-{this.state.totalAmount}
)
}
}
常量产品=(道具)=>(
{props.item.title}
props.handleChangeQuantity(e,props.item.id)}/>
);
render(,document.getElementById(“根”))代码>
实际上,问题是您在setState之后立即调用sum方法,并且setState是异步的,因此当执行sum时,状态没有改变,setState接收到第二个参数,即状态更新后要执行的回调,请参见下面的文档
使基于prevState的sumTotalAmount工作解决了这个问题
sumTotalAmount() {
this.setState( (prevState, props) => { return { totalAmount : prevState.cart.map(( product ) => {
return Number(product.quantity) * Number(product.price);
} ).reduce( ( total, current ) => total += current )}
})
}
const产品=[
{
id:“1”,
标题:“项目1”,
价格:“2450”,
左:“14”,
数量:“1”
},
{
id:“2”,
标题:“项目2”,
价格:“2450”,
左:“178”,
数量:“1”
},
{
id:“3”,
标题:“项目3”,
价格:“2450”,
左:“1”,
数量:“1”
},
{
id:“4”,
标题:“项目4”,
价格:“2450”,
左:“12”,
数量:“1”
}
];
类应用程序扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
产品:这个。道具。产品,
购物车:这个。道具。产品,
总数:0
};
this.handleRemoveProduct=this.handleRemoveProduct.bind(this);
this.handleChangeQuantity=this.handleChangeQuantity.bind(this);
this.sumTotalAmount=this.sumTotalAmount.bind(this);
}
HandlerRemoveProduct(id){
让购物车=this.state.cart;
购物车=购物车。过滤器((产品)=>{
return product.id!=id;
} );
此.setState({
运货马车
} );
这个.sumTotalAmount();
}
HandleChange数量(e,id){
让购物车=this.state.cart;
购物车=购物车.地图((产品)=>{
if(product.id==id){
product.quantity=e.target.value;
}
退货产品;
} );
此.setState({
运货马车
} );
这个.sumTotalAmount();
}
sumTotalAmount(){
this.setState((prevState,props)=>{return{totalAmount:prevState.cart.map((product)=>{
退货编号(产品数量)*编号(产品价格);
})。减少((总计,当前)=>总计+=当前)}
})
}
render(){
返回(
{
this.state.cart.map((项目,索引)=>{
返回(
)
})
}
总额-{this.state.totalAmount}
)
}
}
常量产品=(道具)=>(
{props.item.title}
props.handleChangeQuantity(e,props.item.id)}/>
);
render(,document.getElementById(“根”))代码>
实际上,问题是您在setState之后立即调用sum方法,并且setState是异步的,因此当执行sum时,状态没有改变,setState接收到第二个参数,即状态更新后要执行的回调,请参见下面的文档
使基于prevState的sumTotalAmount工作解决了这个问题
sumTotalAmount() {
this.setState( (prevState, props) => { return { totalAmount : prevState.cart.map(( product ) => {
return Number(product.quantity) * Number(product.price);
} ).reduce( ( total, current ) => total += current )}
})
}
const产品=[
{
id:“1”,
标题:“项目1”,
价格:“2450”,
左:“14”,
数量:“1”
},
{
id:“2”,
标题:“项目2”,
价格:“2450”,
左:“178”,
数量:“1”
},
{
id:“3”,
标题:“项目3”,
价格:“2450”,
左:“1”,
数量:“1”
},
{
id:“4”,
标题:“项目4”,
价格:“2450”,
左:“12”,
数量:“1”
}
];
类应用程序扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
产品:这个。道具。产品,
购物车:这个。道具。产品,
总数:0
};
this.handleRemoveProduct=this.handl
Total amount - {this.state.cart.map( ( product ) => {
return Number(product.quantity) * Number(product.price)
}).reduce( ( total, current ) => total += current )}
constructor( props ) {
super( props );
this.handleRemoveProduct = this.handleRemoveProduct.bind( this );
this.handleChangeQuantity = this.handleChangeQuantity.bind( this );
this.sumTotalAmount = this.sumTotalAmount.bind( this );
this.state = {
products: this.props.products,
cart: this.props.products,
totalAmount: this.sumTotalAmount(this.props.products)
};
}
handleRemoveProduct( id ) {
let cart = this.state.cart;
cart = cart.filter( ( product ) => {
return product.id != id;
} );
this.setState( {
cart: cart,
totalAmount: this.sumTotalAmount(cart)
} );
//this.sumTotalAmount(cart);
}
// Make a similar change to handleChangeQuantity
sumTotalAmount(cart) {
//let cart = this.state.cart;
let totalAmount = cart.map( ( product ) => {
return Number(product.quantity) * Number(product.price);
} ).reduce( ( total, current ) => total += current );
//this.setState( {
// totalAmount
//} );
return totalAmount;
}
this.setState({
cart: newCart
}, () => {
this.sumTotalAmount();
})
this.setState({
cart: newCart,
sum: calculateSum(newCart),
})
this.setState({
cart: newCart,
})
// in render...
<div className="cart__total">
Total amount - {calculateSum(this.state.cart)}
</div>