我是本机反应的新手,正在尝试制作GSTCalculator App。我在计算器屏幕上从用户获取值,并在结果屏幕上显示计算出的值。我的问题是计算出的值不会立即显示在“结果”屏幕上。我什至使用异步和等待。但是它只显示第一个计算值。
calculate = async() => {
await this.calculateSum();
this.props.navigation.navigate('Result', {prodCost: this.state.prodCost,
mfdProfitMargin: this.state.mfdProfitMargin, mCost: this.state.mCost, whProfit: this.state.whProfit,
rtProfit: this.state.rtProfit, cgst: this.state.cgst, sgst: this.state.sgst, igst: this.state.igst,
igstV: this.state.igstV, m2wV: this.state.m2wV, w2rT: this.state.w2rT, whProfitV: this.state.whProfitV,
cgstV: this.state.cgstV, sgstV: this.state.sgstV, w2rV :this.state.w2rV, rtProfitV: this.state.rtProfitV })
}
calculateSum = () => {
this.setState({mCost: Number(this.state.prodCost) + Number(this.state.mfdProfitMargin)});
this.setState({igstV: (Number(this.state.mCost)*Number(this.state.igst))/100});
this.setState({m2wV: Number(this.state.mCost) + Number(this.state.igstV)});
this.setState({whProfitV: (this.state.m2wV)*Number(this.state.whProfit)/100});
this.setState({w2rT: Number(this.state.m2wV) + Number(this.state.whProfitV)});
this.setState({cgstV: (this.state.w2rT)*Number(this.state.cgst)/100});
this.setState({sgstV: (this.state.w2rT)*Number(this.state.sgst)/100});
this.setState({w2rV: Number(this.state.w2rT) + Number(this.state.cgstV) + Number(this.state.sgstV)});
this.setState({rtProfitV: (this.state.w2rV)*Number(this.state.rtProfit)/100});
}
export default class Result extends Component {
constructor(props) {
super(props);
this.state = { pCost: this.props.navigation.state.params.prodCost, pMargin: this.props.navigation.state.params.mfdProfitMargin,
mCost:this.props.navigation.state.params.mCost, igstP: this.props.navigation.state.params.igst,
igstV: this.props.navigation.state.params.igstV, cgstP: this.props.navigation.state.params.cgst,
cgstV: this.props.navigation.state.params.cgstV, sgstP: this.props.navigation.state.params.sgst,
sgstV: this.props.navigation.state.params.sgstV, m2wV: this.props.navigation.state.params.m2wV,
whProfit: this.props.navigation.state.params.whProfit, whProfitV: this.props.navigation.state.params.whProfitV,
w2rT: this.props.navigation.state.params.w2rT, w2rV: this.props.navigation.state.params.w2rV,
rtProfit:this.props.navigation.state.params.rtProfit, rtProfitV: this.props.navigation.state.params.rtProfitV
}
}
render() {
return(
<View>
<ImageBackground source={require('../Assets/login.jpg')} style={Styles.bgImage}>
<ScrollView contentContainerStyle={GStyle.container}>
<View>
<Text style={[Styles.heading, {marginTop: 20}]}>Manufacturer to Wholesaler:</Text>
<View style={GStyle.inputView}>
<Text style={[GStyle.text, {marginTop:10}]}>Production Cost</Text>
<Text style={GStyle.resultText}>{this.state.pCost}</Text>
</View>
<View style={GStyle.inputView}>
<Text style={GStyle.text}>Profit Margin</Text>
<Text style={GStyle.resultText}>{this.state.pMargin}</Text>
</View>
<View style={GStyle.inputView}>
<Text style={GStyle.text}>Manufacture Cost</Text>
<Text style={GStyle.resultText}>{this.state.mCost}</Text>
</View>
<View style={GStyle.inputView}>
<Text style={GStyle.text}>IGST({this.state.igstP}%)</Text>
<Text style={GStyle.resultText}>{this.state.igstV}</Text>
</View>
<View style={GStyle.inputView}>
<Text style={GStyle.text}>Invoice Value</Text>
<Text style={GStyle.resultText}>{this.state.m2wV}</Text>
</View>
</View>
<View>
<Text style={[Styles.heading, {marginTop: 20}]}>Wholesaler to Retailer:</Text>
<View style={GStyle.inputView}>
<Text style={GStyle.text}>Cost to Wholesaler</Text>
<Text style={GStyle.resultText}>{this.state.m2wV}</Text>
</View>
<View style={GStyle.inputView}>
<Text style={GStyle.text}>Profit Margin({this.state.whProfit}%)</Text>
<Text style={GStyle.resultText}>{this.state.whProfitV}</Text>
</View>
<View style={GStyle.inputView}>
<Text style={GStyle.text}>Total</Text>
<Text style={GStyle.resultText}>{this.state.w2rT}</Text>
</View>
<View style={GStyle.inputView}>
<Text style={GStyle.text}>CGST({this.state.cgstP}%)</Text>
<Text style={GStyle.resultText}>{this.state.cgstV}</Text>
</View>
<View style={GStyle.inputView}>
<Text style={GStyle.text}>SGST({this.state.sgstP}%)</Text>
<Text style={GStyle.resultText}>{this.state.sgstV}</Text>
</View>
<View style={GStyle.inputView}>
<Text style={GStyle.text}>Invoice Value</Text>
<Text style={GStyle.resultText}>{this.state.w2rV}</Text>
</View>
</View>
<View>
<Text style={[Styles.heading, {marginTop: 20}]}>Retailer to Consumer:</Text>
<View style={GStyle.inputView}>
<Text style={GStyle.text}>Cost to Retailer</Text>
<Text style={GStyle.resultText}>{this.state.w2rV}</Text>
</View>
<View style={GStyle.inputView}>
<Text style={GStyle.text}>ProfitMargin({this.state.rtProfit}%)</Text>
<Text style={GStyle.resultText}>{this.state.rtProfitV}</Text>
</View>
</View>
</ScrollView>
</ImageBackground>
</View>
);
}
}
答案 0 :(得分:1)
我认为我们可以减少很多状态设置,并且可以做一些重构以使您的代码更易于阅读。
您要一遍又一遍地输入相同的内容,这会使您的构造函数难以理解。
在此示例中,我们采用了值this.props.navigation.state.params
并将其设置为它自己的变量。这意味着您不必一遍又一遍地输入this.props.navigation.state.params
。
constructor(props) {
super(props);
const params = this.props.navigation.state.params
this.state = {
pCost: params.prodCost,
pMargin: params.mfdProfitMargin,
mCost:params.mCost,
igstP: params.igst,
igstV: params.igstV,
cgstP: params.cgst,
cgstV: params.cgstV,
sgstP: params.sgst,
sgstV: params.sgstV,
m2wV: params.m2wV,
whProfit: params.whProfit,
whProfitV: params.whProfitV,
w2rT: params.w2rT,
w2rV: params.w2rV,
rtProfit:params.rtProfit,
rtProfitV: params.rtProfitV
}
}
如果我们使用传播运算符,则可以使此操作更加容易,也就是说,如果您愿意使用与传递的对象相同的名称。
constructor(props) {
super(props);
this.state = {
...this.props.navigation.state.params
}
}
但是,如果使用此方法,则会发现您选择的某些唯一名称将消失,由传递的对象中的唯一名称代替。
我假设您会选择第一个选项(因为它不会更改名称),所以我将在此基础上进行下一个重构。
这里的setStates太多,需要花费一些时间来设置状态,因此您可能在以后的计算中使用旧值,因此最好在执行所有计算之前不要使用setState。如果每个setState的值都取决于先前的值,那么您可以执行类似的操作,仅在必要时使用初始状态中的值。
calculateSum () => {
let mCost = Number(this.state.prodCost) + Number(this.state.mfdProfitMargin);
let igstV = mCost * Number(this.state.igst) / 100;
let m2wV = mCost + igstV;
let whProfitV = m2wV * Number(this.state.whProfit)/100;
let w2rT = m2wV + whProfitV;
let cgstV = w2rT * Number(this.state.cgst)/100;
let sgstV = w2rT * Number(this.state.sgst)/100;
let w2rV = w2rT + cgstV + sgstV;
let rtProfitV = w2rV * Number(this.state.rtProfit)/100;
return { mCost, igstV, m2wV, whProfitV, w2rT, cgstV, sgstV, w2rV, rtProfitV }
}
在这里,我返回一个具有所有更新值的对象,如果我们选择的话,可以将其保存为状态。
由于calculateSum
函数现在返回一个具有您想要的所有值的对象,您可以执行以下操作。我们采用刚刚计算出的总和对象,并使用散布运算符将所有这些对象设置为状态。然后,我们在setState函数上使用回调,然后导航到下一页,再次使用spread操作符捕获处于状态的所有值。
calculate = () => {
let sum = this.calculateSum();
this.setState({...sum}, () => {
this.props.navigation.navigate('Result', {...this.state })
});
}
但是,如果不需要将这些值保存到状态并仅传递到下一个屏幕,我们可以将calculate
函数更新为类似的内容
calculate = () => {
let sum = this.calculateSum();
this.props.navigation.navigate('Result', {...this.state, ...sum })
}
希望这对您有所帮助。
有关JavaScript中的传播算子的更多信息,请参见本文 https://zendev.com/2018/05/09/understanding-spread-operator-in-javascript.html
有关设置状态的更多信息,请查阅这两篇文章 https://medium.learnreact.com/setstate-is-asynchronous-52ead919a3f0 https://medium.learnreact.com/setstate-takes-a-callback-1f71ad5d2296