0

I'll admit that there are other questions with issues similar to this, but I am struggling to understand how to implement their answers in my solution.

I am creating a tip calculator app using react-native, and the idea is to have the subtotal default to 0, the tip percent default to 20%, and the bill total default to 0. When the user starts to type in the subtotal, the characters are being captured one behind. For example, when I type "1" - the value in state is still 0, but when I continue to type "10", the value in state becomes 1 (a character behind).

Example console output:

[Wed Nov 18 2020 21:59:20.241]  LOG      Subtotal: 
[Wed Nov 18 2020 21:59:20.242]  LOG      Tip: 18
[Wed Nov 18 2020 21:59:20.251]  LOG      Subtotal Float: 0
[Wed Nov 18 2020 21:59:20.252]  LOG      Tip Float: 0.18
[Wed Nov 18 2020 21:59:22.654]  LOG      Subtotal: 1
[Wed Nov 18 2020 21:59:22.656]  LOG      Tip: 18
[Wed Nov 18 2020 21:59:22.656]  LOG      Subtotal Float: 1
[Wed Nov 18 2020 21:59:22.657]  LOG      Tip Float: 0.18

Code: App.js

  const [subtotal, setSubtotal] = useState('');
  const [tipPercent, setTipPercent] = useState(20);

  const [subtotalFloat, setSubtotalFloat] = useState(0.0);
  const [tipPercentFloat, setTipPercentFloat] = useState(.2);
  const [billTotalFloat, setBillTotalFloat] = useState(0.0);

  const handleSubtotalChange = (newSubtotal) => {
    setSubtotal(newSubtotal);
    setSubtotalFloat(Number.parseFloat(newSubtotal));
      console.log("Subtotal: " + subtotal);
      console.log("Tip: " + tipPercent);
      console.log("Subtotal Float: " + subtotalFloat);
      console.log("Tip Float: " + tipPercentFloat);
    setBillTotalFloat(calculateBillTotal());
  };

  const handleTipPercentChange = (newTipPercent) => {
    setTipPercent(newTipPercent);
    setTipPercentFloat(Number.parseFloat(newTipPercent) / 100);
    setBillTotalFloat(calculateBillTotal());
  };

  const calculateBillTotal = () => {
    return (subtotalFloat + (subtotalFloat * tipPercentFloat));
  };



  return (
  <View  style={styles.container}>
    <View style={styles.header}>
      <AppHeader />
    </View>
    <View style={styles.subtotal}>
      <SubtotalEntry {...{subtotal, handleSubtotalChange}} />
    </View>
    <View style={styles.tip}>
      <TipEntry {...{tipPercent, billTotalFloat, handleTipPercentChange}} />
    </View>
  </View>
  );
};

SubtotalEntry.js

const SubtotalEntry = (props) => {
    return (
        <View>
            <Text style={styles.header}>Input Subtotal</Text>
            <Input keyboardType={'decimal-pad'} placeholder='$$$' value={props.subtotal} onChangeText={props.handleSubtotalChange} />
        </View>
    );
};

I understand that setting state is asynchronous - but I'm unsure if that means I should enclose the float calculations in an await OR use useEffect() to do the calculations.

Thank you!

freefall
  • 319
  • 1
  • 8
  • 1
    You will likely need to use an `useEffect` hook to compute a total based on the user entered values and sub-total *after* those update in state. – Drew Reese Nov 19 '20 at 05:18
  • @DrewReese you are right - and the auto-suggested answer was a great explanation of why useState didn't work as I expected in this scenario – freefall Nov 19 '20 at 05:48

0 Answers0