Home > Software design >  React Native OnChange getting triggered but not updating state
React Native OnChange getting triggered but not updating state

Time:01-08

i am trying to accomplish that when the user enter 2 numbers (eg. am1=5555 and am2=55).

the outcome of the divide function does am2/100 (55/100 = 0.55) the outcome of the add function does (am1 0.55=5555.55) the outcome of the multiply function does ((5555.55*5%) 5555.55 100) "TOTAL"

What i am trying to on here is when the user changes the values of am1 or am2 the TOTAL automatically changes.

I tried doing the following using the onChange and updating the state but this didnt work using the code below.

AmountScreen.js

    import React,{useState} from 'react';
    import {View, StyleSheet,Text,TextInput,TouchableOpacity,ScrollView,Alert} from 
    'react-native';

      import {AppForm} from "../../components/forms";

      function EnterAmountScreen() {

      const[am1,Setam1]=useState(0)
      const[am2,Setam2]=useState(0)

      const divide = (num1, num2) => {
        return num1 / num2;
      };

      let resuldivide = divide(am2, 100);
      console.log("/:",resuldivide);

      const add = (num1, num2) => {
        return num1   num2;
      };

      let resuladd = add(Number(am1), Number(resuldivide));
      console.log(" :",resuladd);

      const multiply = (num1, num2) => {
        return num1 * num2;
      };

      let resulmultiply = multiply(Number(resuladd), 0.05);
      console.log("%:",parseFloat(resulmultiply).toFixed(2));

      const total=(num1,num2,num3)=>{
        return num1   num2   num3;
      };

       let resultotal = 
       total(Number(resuladd),Number(parseFloat(resulmultiply).toFixed(2)),Number(100));
       console.log("=:",parseFloat(resultotal).toFixed(2));    
       
       console.log("am1:",am1)
    
     const changeam1State = ({am1,am2}) => {
        Setam1(am1);
        console.log('new am1',am1)
     }

    return(
       <View>
        <AppForm
        initialValues={{ 
            amount1:am1,
            amount2:am2,
        }}>
          <View> 
          <View>
          <TextInput
          name="amount1"
          autoCorrect={false}
          autoFocus
          contextMenuHidden={true}
          keyboardType="ascii-capable"
          keyboardType="numeric"
          onChange={changeam1State}
          value={am1}
          />
           <Text>.</Text>
          <TextInput
            name="amount2"
            autoCorrect={false}
            placeholder="00"
            keyboardType="numeric"
            contextMenuHidden={true}
          />
          </View>

              <Text>{parseFloat(resultotal).toFixed(2)}</Text>

              <Text>am1: {am1} </Text>
              <Text>am2: {am2} </Text>
        
        </View>
      </AppForm>

       </View>
    );
    }

    export default EnterAmountScreen;

AppForm.js

    import React from "react";
    import { Formik } from "formik";

    function AppForm({ initialValues, onSubmit, validationSchema, children }) {
    return (
    <Formik
      initialValues={initialValues}
      onSubmit={onSubmit}
      validationSchema={validationSchema}
    >
      {() => <>{children}</>}
    </Formik>
    );
    }

    export default AppForm;

CodePudding user response:

you did not integrated formik correctly you can refer to this official doc

you don’t need to use states to keep form values formik does that for you.

you'll receive { handleChange, handleBlur, handleSubmit, values } as props from <Formik> Component and you have to use it. for your usecase you can do without formik as well.

here is sample code to integrate formik with your component

AmountScreen.js

import React, { useState } from "react";
import { View, Text, TextInput } from "react-native";

import AppForm from "./AppForm";

function EnterAmountScreen() {
  const Form = ({ handleChange, handleSubmit, values }) => {
    const { amount1, amount2 } = values;
    const divide = (num1, num2) => {
      return num1 / num2;
    };

    let resuldivide = divide(amount2, 100);
    console.log("/:", resuldivide);

    const add = (num1, num2) => {
      return num1   num2;
    };

    let resuladd = add(Number(amount1), Number(resuldivide));
    console.log(" :", resuladd);

    const multiply = (num1, num2) => {
      return num1 * num2;
    };

    let resulmultiply = multiply(Number(resuladd), 0.05);
    console.log("%:", parseFloat(resulmultiply).toFixed(2));

    const total = (num1, num2, num3) => {
      return num1   num2   num3;
    };

    let resultotal = total(
      Number(resuladd),
      Number(parseFloat(resulmultiply).toFixed(2)),
      Number(100)
    );
    console.log("=:", parseFloat(resultotal).toFixed(2));

    return (
      <View>
        <View>
          <TextInput
            name="amount1"
            autoCorrect={false}
            autoFocus
            contextMenuHidden={true}
            keyboardType="ascii-capable"
            keyboardType="numeric"
            onChange={handleChange("amount1")}
            value={values?.amount1}
          />
          <Text>.</Text>
          <TextInput
            name="amount2"
            autoCorrect={false}
            placeholder="00"
            keyboardType="numeric"
            contextMenuHidden={true}
            value={values?.amount2}
            onChange={handleChange("amount2")}
          />
        </View>

        <Text>{parseFloat(resultotal).toFixed(2)}</Text>

        <Text>
          {"am1:"} {values.amount1}{" "}
        </Text>
        <Text>
          {"am2:"} {values.amount2}{" "}
        </Text>
      </View>
    );
  };

  return (
    <View>
      <AppForm
        initialValues={{
          amount1: 0,
          amount2: 0
        }}
        Component={Form}
      ></AppForm>
    </View>
  );
}

export default EnterAmountScreen;

AppForm.js

import React from "react";
import { Formik } from "formik";

function AppForm({ initialValues, onSubmit, validationSchema, Component }) {
  return (
    <Formik
      initialValues={initialValues}
      onSubmit={onSubmit}
      validationSchema={validationSchema}
    >
      {({ handleChange, handleBlur, handleSubmit, values }) => (
        <Component
          handleChange={handleChange}
          handleSubmit={handleSubmit}
          values={values}
        />
      )}
    </Formik>
  );
}

export default AppForm;

codesandbox demo code : https://codesandbox.io/s/crazy-sound-04jvx?file=/src/AppForm.js:0-523

  •  Tags:  
  • Related