通过反应导航传递多个道具

时间:2019-01-21 07:10:30

标签: react-native parameters react-navigation

我是本机反应的新手,正在尝试制作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>
    );
}

}

1 个答案:

答案 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

相关问题