React-native:当输入有空文本时计算返回 NaN

pro*_*rog 2 javascript reactjs react-native

我正在使用 React-Native 构建一个费用计算器,并且我有多个输入字段,用于设置计算变量。

当输入字段具有正确的值时,一切正常,但是如果用户在之前输入的内容上按退格键,然后尝试使用空字段计算利润,则总数将显示为 NaN。

到目前为止,这是我的代码:

this.state = {
       text: '',
       soldPrice: 0,
       shippingCost: 0,
       shippingCharge: 0,
       itemCost: 0,
       profit: 0,
       paypalFee: 0.30,
       paypalFeePercentage: 0.029,
       ebayFee: 0.1
     };
  }

  calculateProfit = () => {
    const { soldPrice, shippingCost, shippingCharge, itemCost,
      paypalFee, ebayFee, paypalFeePercentage
     } = this.state;


     let sp = parseFloat(soldPrice);
     const sc = parseFloat(shippingCost);
     const sCharge = parseFloat(shippingCharge);
     const ic = parseFloat(itemCost);
     const pf = parseFloat(paypalFee);
     const ef = parseFloat(ebayFee);
     const pfp = parseFloat(paypalFeePercentage);

// sp = soldPrice, sc = shippingCost,
// sCharge = shippingCharge, ic = itemCost,
// pf = paypalFee, ef = ebayFee, pfp = paypalFeePercentage, c = calculation


     const calculation = sp - sp * pfp -
     pf
     - sp * ef - sc
     - ic;

     sp += sCharge;

     if (!this.state.itemCost) {
       this.setState({ itemCost: 0 });
     }

     let i;
// if profit is more than 10 than the profit will be displayed as 00.00
// otherwise it will be displayed as 0.00
     if (calculation > 1000) {
       i = 6;
     } else if (calculation > 100) {
       i = 5;
     } else if (calculation > 10) {
       i = 4;
     }
     const roundedNumber = calculation.toPrecision(i);
    this.setState({
      profit: roundedNumber
    });
  }

 render() {
   return (
     <View style={styles.container}>

     <View style={styles.header}>
     <Text style={styles.headerText}>Efees</Text>
     </View>

     <View style={styles.blocks}>

     <View style={styles.inputs}>
     <Text style={styles.inputText}>Sold Price</Text>

     <TextInput
         underlineColorAndroid='transparent'
         style={styles.TextInputStyle}
         placeholder='0.00'
         keyboardType={'numeric'}
         value={this.state.soldPrice}
         onChangeText={(soldPrice) => this.setState({ soldPrice })}
     />

     </View>

     <View style={styles.inputs}>
     <Text style={styles.inputText}>Shipping Charge</Text>

     <TextInput
         underlineColorAndroid='transparent'
         style={styles.TextInputStyle}
         placeholder='0.00'
         keyboardType={'numeric'}
         value={this.state.shippingCharge}
         onChangeText={(shippingCharge) => this.setState({ shippingCharge })}
     />

     </View>

     <View style={styles.inputs}>
     <Text style={styles.inputText}>Shipping Cost</Text>

     <TextInput
         underlineColorAndroid='transparent'
         style={styles.TextInputStyle}
         placeholder='0.00'
         keyboardType={'numeric'}
         value={this.state.shippingCost}
         onChangeText={(shippingCost) => this.setState({ shippingCost })}
     />

     </View>

     <View style={styles.inputs}>
     <Text style={styles.inputText}>Item Cost</Text>

     <TextInput
         underlineColorAndroid='transparent'
         style={styles.TextInputStyle}
         placeholder='0.00'
         keyboardType={'numeric'}
         value={this.state.itemCost}
         onChangeText={(itemCost) => this.setState({ itemCost })}
     />

     </View>

     <View style={styles.inputs}>



            </View>

     </View>

     <TouchableOpacity
     style={styles.calcButton}
     onPress={this.calculateProfit}
     >
        <Text style={styles.calcText}>Calculate </Text>
      </TouchableOpacity>

      <Text>{`Profit: $${this.state.profit}`}</Text>


      </View>
 );
 }
}
Run Code Online (Sandbox Code Playgroud)

Dac*_*nny 6

这里的问题是由于尝试解析空字符串时parseFloat()返回引起的:Number.NaN

/* Parse a valid value */
console.log( parseFloat('1.2') , '===', 1.2 );

/* Parse an empty string yields NaN */
console.log( parseFloat('') , '===', Number.NaN );
Run Code Online (Sandbox Code Playgroud)

Number.NaN通过一个或多个变量将 a 引入后续计算的算术时, 的值calculation将是Number.NaN

const sp = 1,
      pfp = 1,
      ef = 1,
      pf = 1,
      sc = 1,
      ic = Number.NaN;

const calculation = sp - sp * pfp - pf - sp * ef - sc - ic;

console.log(calculation);
Run Code Online (Sandbox Code Playgroud)

有很多方法可以解决此问题 - 只需对当前代码进行最少更改的简单方法如下:

calculateProfit = () => {
  const {
    soldPrice,
    shippingCost,
    shippingCharge,
    itemCost,
    paypalFee,
    ebayFee,
    paypalFeePercentage
  } = this.state;

  /* 
  Define helper function that recovers a 0 as a default value
  if "non-a-number" results from parseFloat
  */
  const safeParseFloat = (str) => {

    const value = Number.parseFloat(str);

    return Number.isNaN(value) ? 0 : value;    
  }

  /*
  Use locally defined helper to safely parse strings while also
  accounting form empty string mapping to 0
  */
  let sp = safeParseFloat(soldPrice);
  const sc = safeParseFloat(shippingCost);
  const sCharge = safeParseFloat(shippingCharge);
  const ic = safeParseFloat(itemCost);
  const pf = safeParseFloat(paypalFee);
  const ef = safeParseFloat(ebayFee);
  const pfp = safeParseFloat(paypalFeePercentage);

  const calculation = sp - sp * pfp - pf - sp * ef - sc - ic;

  sp += sCharge;

  if (!this.state.itemCost) {
    this.setState({
      itemCost: 0
    });
  }

  let i;
  // if profit is more than 10 than the profit will be displayed as 00.00
  // otherwise it will be displayed as 0.00
  if (calculation > 1000) {
    i = 6;
  } else if (calculation > 100) {
    i = 5;
  } else if (calculation > 10) {
    i = 4;
  }
  const roundedNumber = calculation.toPrecision(i);

  this.setState({
    profit: roundedNumber
  });
}
Run Code Online (Sandbox Code Playgroud)