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;
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>
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;
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} />
</>
);
};