setState is not updating for TextInput using hooks in React Native

Viewed 25

I have created a program which takes feet and inches as input and converts them into meters and centimeters. The conversion logic is written in useEffect Hook and the logic is working fine and I'm getting the correct answer in console, but the meters is not being displayed on the screen. When I type input I'm only getting output in centimeters but not in meters. Meters is textInput is always blank. Please help!

import React, {useState, useEffect} from 'react';
import {
  View,
  StyleSheet,
  StatusBar,
  Dimensions,
  Image,
  Text,
  TextInput,
} from 'react-native';

import colors from '../constants/colors';
import {Button} from '../components/Button';

const screen = Dimensions.get('window');

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: colors.blue,
  },
  content: {
    paddingTop: screen.height * 0.1,
  },
  logoContainer: {
    alignItems: 'center',
    justifyContent: 'center',
    marginBottom: 20,
  },
  logoBackground: {
    width: screen.width / 0.45,
    height: screen.width * 0.45,
  },
  logo: {
    position: 'absolute',
    width: screen.width * 0.25,
    height: screen.width * 0.25,
  },
  textHeader: {
    color: colors.white,
    fontWeight: 'bold',
    fontSize: 30,
    textAlign: 'center',
    marginBottom: 20,
  },
  text: {
    fontSize: 14,
    color: colors.white,
    textAlign: 'center',
  },
  inputContainer: {
    flexDirection: 'row',
    flex: 1,
    marginBottom: 10,
  },
  header: {
    alignItems: 'flex-end',
    marginHorizontal: 20,
  },
  sideHeading: {
    textAlign: 'center',
    width: screen.width / 5,
    marginTop: 20,
  },
  textBox: {
    textAlign: 'center',
    width: screen.width / 5,
  },
  button: {
    flexDirection: 'row',
    alignItems: 'center',
    flex: 1,
    justifyContent: 'center',
    marginVertical: 20,
    backgroundColor: colors.red,
    width: screen.width / 2,
    marginLeft: screen.width / 3.2,
  },
  buttonText: {
    alignItems: 'center',
    justifyContent: 'center',
    fontSize: 16,
    color: colors.white,
  },
});

export default ({route = {}}) => {
  const params = route.params || {};
  const {
    title,
    baseDefaultFirst,
    baseDefaultSecond,
    quoteDefaultFirst,
    quoteDefaultSecond,
  } = params;

  const [baseValueOne, setBaseValueOne] = useState(baseDefaultFirst);
  const [baseValueTwo, setBaseValueTwo] = useState(baseDefaultSecond);
  const [quoteValueOne, setQuoteValueOne] = useState(quoteDefaultFirst);
  const [quoteValueTwo, setQuoteValueTwo] = useState(quoteDefaultSecond);
  const [firstValue, setFirstValue] = useState(0);
  const [secondValue, setSecondValue] = useState(0);
  const [thirdValue, setThirdValue] = useState(0);
  const [fourthValue, setFourthValue] = useState(0);

  const swapCurrencies = () => {
    setBaseValueOne(quoteValueOne);
    setBaseValueTwo(quoteValueTwo);
    setQuoteValueOne(baseValueOne);
    setQuoteValueTwo(baseValueTwo);
    setFirstValue('');
    setSecondValue('');
    setThirdValue('');
    setFourthValue('');
  };

  useEffect(() => {
    if (baseValueOne === 'FT') {
      const f = parseFloat(firstValue);
      const i = parseFloat(secondValue);
      let finalAnsInCm = parseFloat((12 * f + i) * 2.54);
      const meters = parseInt(finalAnsInCm / 100, 10);
      finalAnsInCm = parseFloat(finalAnsInCm % 100).toFixed(2);
      if (meters != 0 || finalAnsInCm != 0) {
        setThirdValue(meters);
        setFourthValue(finalAnsInCm);
        console.log(meters);
        console.log(finalAnsInCm);
      }
    }
  }, [firstValue, secondValue]);

  return (
    <View style={styles.container}>
      <StatusBar barStyle="light-content" backgroundColor={colors.blue} />
      <View style={styles.content}>
        <View style={styles.logoContainer}>
          <Image
            source={require('../assets/images/background.png')}
            style={styles.logoBackground}
            resizeMode="contain"
          />
          <Image
            source={require('../assets/images/logo.png')}
            style={styles.logo}
            resizeMode="contain"
          />
        </View>
        <Text style={styles.textHeader}>
          {title}
          {' '}
          Converter
        </Text>

        {/* Input */}
        <View style={styles.inputContainer}>
          <Text style={styles.sideHeading}>{baseValueOne}</Text>
          <TextInput
            style={styles.textBox}
            value={firstValue}
            keyboardType="numeric"
            onChangeText={text => setFirstValue(text)}
          />
          <Text style={styles.sideHeading}>{baseValueTwo}</Text>
          <TextInput
            style={styles.textBox}
            value={secondValue}
            keyboardType="numeric"
            onChangeText={text => setSecondValue(text)}
          />
        </View>

        <View style={styles.inputContainer}>
          <Text style={styles.sideHeading}>{quoteValueOne}</Text>
          <TextInput
            editable={false}
            style={styles.textBox}
            value={thirdValue}
            keyboardType="numeric"
          />
          <Text style={styles.sideHeading}>{quoteValueTwo}</Text>
          <TextInput
            editable={false}
            style={styles.textBox}
            value={fourthValue}
            keyboardType="numeric"
          />
        </View>

        <Button text={`Reverse ${title}`} onPress={() => swapCurrencies()} />
      </View>
    </View>
  );
};
0 Answers
Related