пройти несколько реквизита по реакции навигации - PullRequest
0 голосов
/ 21 января 2019

Я новичок в реакции-нативном и пытаюсь сделать приложение GSTCalculator. Я беру значения от пользователя на экране калькулятора и показываю рассчитанные значения на экране результатов. Моя проблема в том, что рассчитанные значения не отображаются сразу на экране результатов. Я даже использовал асинхронный и жду. Но он показывает только первое вычисленное значение.

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 голосов
/ 21 января 2019

Существует множество настроек состояния, я думаю, что мы можем уменьшить их, и есть небольшой рефакторинг, который мы можем сделать, чтобы ваш код было легче читать.

Конструктор

Вы печатаете одно и то же снова и снова, и это делает ваш конструктор намного труднее для чтения, чем он должен быть.

В этом примере мы взяли значение 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, чтобы затем перейти к следующей странице, снова используя оператор распространения, чтобы захватить все значения, которые находятся в состоянии.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...