【发布时间】:2020-09-14 19:38:24
【问题描述】:
我正在使用 react typescript 构建订单。该表单允许用户输入quantity、unit price,并选择项目是否为taxable。
我为这个示例简化了我的代码,只展示了添加 1 或 2 个项目的能力。但对于最终产品,他的用户将能够添加大约 10-15 项。所以每个字段将有 15 个。这将被标记为quantity1、quantity2、quantity3 等。
因此,一旦用户选择了数量、单价以及商品是否应纳税。我有一个计算 total extended price 的字段,它只是 quantity * unit price
我也有两个字段。一种为所有项目添加所有税款(这只是用户选择应税到是的项目)。另一个是包含所有税费的总价。
现在一切正常。但以下是我面临的三个问题。当用户进行更改时,问题就开始了。
如果用户选择
taxable到Yes,然后返回No。价格调整了,但Estimated Sales Tax仍然没有反映变化。如果用户选择 5 作为数量,然后更改为 4,再变回 5,则税款会增加两次。
如果在将税款添加到总金额时,税款最终是小数,则数学错误。
这是我的代码:
import * as React from 'react';
export class Screen1 extends React.Component<{}, {
Quantity: number,
UnitPrice: number,
ExtendedPrice: number,
Taxable1: string,
TaxAmount1: number,
Quantity2: number,
UnitPrice2: number,
ExtendedPrice2: number,
Taxable2: string,
TaxAmount2: number,
EstimatedTotal: number;
EstimatedSalesTax: number;
}> {
constructor(props) {
super(props);
this.state = {
Quantity: null,
UnitPrice: null,
ExtendedPrice: null,
Taxable1: '',
TaxAmount1: null,
Quantity2: null,
UnitPrice2: null,
ExtendedPrice2: null,
Taxable2: '',
TaxAmount2: null,
EstimatedTotal: null,
EstimatedSalesTax: 0,
};
this.handleChangeQuantity = this.handleChangeQuantity.bind(this);
this.handleChangeUnitPrice = this.handleChangeUnitPrice.bind(this);
this.handleChangeExtendedPrice = this.handleChangeExtendedPrice.bind(this);
this.handleChangeTaxable1 = this.handleChangeTaxable1.bind(this);
this.handleChangeEstimatedTotal = this.handleChangeEstimatedTotal.bind(this);
this.handleChangeEstimatedSalesTax = this.handleChangeEstimatedSalesTax.bind(this);
}
handleChangeQuantity = async (event: any) => {
const value = parseInt(event.target.value)
await this.setState({ Quantity: value })
console.log(value);
this.handleChangeExtendedPrice()
}
handleChangeUnitPrice = async (event: any) => {
const value = parseInt(event.target.value)
await this.setState({ UnitPrice: value })
console.log(value);
this.handleChangeExtendedPrice()
}
handleChangeTaxable1 = async (event: any) => {
const value = event.target.value;
await this.setState({ Taxable1: value })
console.log(value);
this.handleChangeExtendedPrice()
}
handleChangeExtendedPrice() {
if (this.state.Taxable1 === "Yes") {
this.setState({
ExtendedPrice: (this.state.Quantity * this.state.UnitPrice) + ((this.state.Quantity * this.state.UnitPrice) * .08),
TaxAmount1: (this.state.Quantity * this.state.UnitPrice) * .08
});
} else {
this.setState({
ExtendedPrice: this.state.Quantity * this.state.UnitPrice,
});
}
console.log(this.state.ExtendedPrice);
this.handleChangeEstimatedTotal();
}
handleChangeEstimatedSalesTax = async () => {
await this.setState({
EstimatedSalesTax: this.state.TaxAmount1 + this.state.TaxAmount2,
});
console.log(this.state.EstimatedSalesTax);
}
handleChangeEstimatedTotal = async () => {
await this.setState({
EstimatedTotal: this.state.ExtendedPrice + this.state.ExtendedPrice2 + this.state.EstimatedSalesTax,
});
console.log(this.state.EstimatedTotal);
this.handleChangeEstimatedSalesTax();
}
public render(): React.ReactElement<{}> {
return (
<div>
<form onSubmit={this._onNewRequest}>
<div>
<div>
<label>
Quantity <br /> (Units)
</label>
<input
value={this.state.Quantity}
onChange={this.handleChangeQuantity}
type="number"
maxLength={9}
pattern='[0-9]{0,5}'
/>
</div>
<div>
<label>
Estimated<br /> Unit Price
</label>
<input
value={this.state.UnitPrice}
onChange={this.handleChangeUnitPrice}
type="number"
pattern='[0-9]{0,5}'
prefix={'$'}
/>
</div>
<div>
<label>
Estimated<br /> Extended Price
</label>
<input
value={this.state.ExtendedPrice}
//onChange={(e) => this.handleChangeUnitPrice(e)}
type="number"
disabled
/>
</div>
<div>
<label>
Taxable?
</label>
<select name="Taxable1" value={this.state.Taxable1} onChange={this.handleChangeTaxable1}>
<option value="No">No</option>
<option value="Yes">Yes</option>
</select>
</div>
</div>
<div>
<div>
<label>
Estimated Sales Tax
</label>
<input
value={this.state.EstimatedSalesTax}
type="number"
disabled
/>
</div>
<div>
<label>
Estimated Total
</label>
<input
value={this.state.EstimatedTotal}
type="number"
disabled
/>
</div>
</div>
</form>
);
}
}
【问题讨论】:
-
您不应等待
setState。如果您想在更新后做某事,可以使用回调样式this.setState({ Quantity: value }, this.handleChangeExtendedPrice); -
@topched 当我删除等待时。自为征税。然后它在加载时执行。所以在数量和单价之前可以填写。它会说我的税是0.8。难以解释。我也不是最擅长反应的。
-
很难说发生了什么。删除所有 async 和 await 关键字,然后在状态更新后使用回调样式运行操作。请注意,当您执行 setState() 和 console.log(this.state) 时,不能保证此时 this.state 会更新。状态更新不是同步的,它们是由 react 安排的,可以批量处理
标签: javascript reactjs typescript async-await react-redux