Home > Software engineering >  how to get current value from input field in react js
how to get current value from input field in react js

Time:05-28

I am trying to get current value from input field, but after onclick I am getting preious value in colsole. here is my code

    import { React, useState } from "react";

const CompoundIntrest = () => {
  const [capitalValue, setcapitalValue] = useState(1000);
  const ChangeCapital = () => {
    setcapitalValue(capitalValue - 100);
  };
  const Calculate = () => {
    console.log(capitalValue);
  };

  return (
    <>
      <button
        onClick={() => {
          ChangeCapital();
          Calculate();
        }}
      >
        click
      </button>
      <input type="number" value={capitalValue} />
    </>
  );
};

export default CompoundIntrest;

CodePudding user response:

State updates occur asynchronously, so you won't have the updated state value inside the event handler.

You can lift the new value i.e. capitalValue - 100 to a scope from where it can be passed down to both ChangeCapital & Calculate.

const CompoundIntrest = () => {
  const [capitalValue, setCapitalValue] = React.useState(1000);

  const handleClick = () => {
    const newCapitalValue = capitalValue - 100;
    ChangeCapital(newCapitalValue);
    Calculate(newCapitalValue);
  };
  const ChangeCapital = (capitalValue) => {
    setCapitalValue(capitalValue);
  };
  const Calculate = (capitalValue) => {
    console.log(capitalValue);
  };

  return (
    <React.Fragment>
      <button onClick={handleClick}>click</button>
      <input
        type="number"
        value={capitalValue}
        onChange={(e) => setCapitalValue(e.target.value)}
      />
    </React.Fragment>
  );
};

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<CompoundIntrest />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="root"></div>

Note: The state updater function is called synchronously but the state updates happen asynchronously.

This becomes more clear if you update the state by passing a state updater callback, you would see that the callback is fired synchronously. Notice the order of logs in the example below:

function App() {
  const [count, setCount] = React.useState(0);

  const handleClick = () => {
    console.log("Before calling setCount");
    setCount((currCount) => {
      console.log("Inside setCount");
      return currCount   1;
    });
    console.log("After calling setCount");
  };

  return <button onClick={handleClick}>Count: {count}</button>;
}

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="root"></div>

CodePudding user response:

You can use Use useEffect Like this:-

import React,{useState,useEffect} from "react";

const CompoundIntrest  = () => {
  const [capitalValue, setcapitalValue] = useState(1000);
  const ChangeCapital = () => {
    setcapitalValue(capitalValue - 100);
  };
  const Calculate = () => {
    console.log(capitalValue);
  };
  useEffect(()=>{
    console.log("afet chage",capitalValue);
  },[capitalValue]);
  return (
    <>
    <button
        onClick={() => {
          ChangeCapital();
          Calculate();
        }}
      >
        click
      </button>
      <input type="number" value={capitalValue} />
    </>
  );
};

CodePudding user response:

You can use the onChange event in the input field to get current value.

const [currentValue, setCurrentValue] = useState['']

const changeHandler = (e:any) => {
  e.preventDefault();
  const { value } = e.target
  console.log('value', value);
  setCurrentValue(value)
}
<input type="string" value={currentValue} onChange={(e:any) => changeHandler(e)}/>

CodePudding user response:

I think, you should add onChange method in input tag like below:

Then you get current value in onClick event in button tag.

import { React, useState } from "react";

const CompoundIntrest = () => {
  const [capitalValue, setcapitalValue] = useState(1000);
  const ChangeCapital = () => {
    setcapitalValue(capitalValue - 100);
  };
  

  useEffect(() => {
    const Calculate = () => {
      console.log(capitalValue);
    };
    Calculate()
  }, [capitalValue])
  

  return (
    <>
      <button
        onClick={() => {
          ChangeCapital();
        }}
      >
        click
      </button>
      <input type="number" value={capitalValue} onChange={(e) => setcapitalValue(e.target.value)} />
    </>
  );
};

export default CompoundIntrest;

CodePudding user response:

your code is fine, and your state is successfuly updated, the problem is the timing of calling your console. react handles your code async, it means it starts your changeCapital, and before the change capital function is finished it calls the calculate function, so the value of your state, is the previous value.

you need to call your calculate function somewhere else:

  1. you can call it in a UseEffect hook, this way your function gets called whenever your state has successfuly changed, or

  2. you can call your calculate in 'onchange' event of your input feild

if you want the better solution, the first one is more reactly than the second one

  • Related