I don't know why the handleSum
function doesn't sum the updated value came from handleInput
when I invoke the function handleAll
through the onChange
input event. It seems that sums with the previous value. Can you bring some light here? Thank you!
Here the JS part:
const card = () => {
//hook defined
const [input, setInput] = React.useState({
p1h1: "",
p1h2: "",
});
const [result, setResult] = React.useState("")
//handle input change
const handleInput = function(e){
setInput({
...input,
[e.target.name]: e.target.value
});
};
//handle sum
const handleSum = function(){
const { p1h1, p1h2 } = input;
setResult(Number(p1h1) Number(p1h2));
}
//handle result player
const handleAll = function (e) {
handleInput(e)
setTimeout (()=> {handleSum()},1000) // I inserted this setTimeout to double sure that this is executing after the previous function but didn't work.
}
}
Here the HTML part:
<input
name= "p1h1"
value={input.p1h1}
onChange={handleAll}
type= "number"
min="0"
</input>
<input
name= "p1h2"
value={input.p1h2}
onChange={handleAll}
type= "number"
min="0"
</input>
<h2>Result sum: {result}</h2>
CodePudding user response:
According to the Rules of Hooks (see my comment) you may not use hooks except at the toplevel of functional components. Not nested in other functions, not in if
not in for
, etc.
So you need to make a functional component, like const Test = () => { return (<div />); }
Then you need to call your hook, and render your HTML as JSX from within that component. You can then use your handleInput
function to update the state.
You do not need another state to hold the result of the addition. It's OK to just compute that during render.
This will work:
const Test = () => {
//hook defined
const [input, setInput] = React.useState({
p1h1: '',
p1h2: '',
});
//handle input change
const handleInput = function (e) {
setInput({
...input,
[e.target.name]: e.target.value,
});
};
const { p1h1, p1h2 } = input;
const result = Number(p1h1) Number(p1h2);
return (
<div>
<input name="p1h1" value={input.p1h1} onChange={handleInput} type="number" min="0"></input>
<input name="p1h2" value={input.p1h2} onChange={handleInput} type="number" min="0"></input>
<h2>Result sum: {result}</h2>
</div>
);
};
CodePudding user response:
The way you are calling handleSum
is not right. You should use a useEffect
hook to re-render the element when a particular state changes as an array of dependencies (2nd argument of useEffect
). You can learn more about it here https://reactjs.org/docs/hooks-effect.html.
const App = () => {
const [input, setInput] = React.useState({
p1h1: "",
p1h2: "",
});
React.useEffect(() => {
handleSum()
}, [input])
const [result, setResult] = React.useState("")
//handle input change
const handleInput = function(e){
setInput({
...input,
[e.target.name]: e.target.value
});
};
//handle sum
const handleSum = function(){
const { p1h1, p1h2 } = input;
setResult(Number(p1h1) Number(p1h2));
}
return (
<div>
<input
name= "p1h1"
value={input.p1h1}
onChange={handleInput}
type= "number"
min="0">
</input>
<input
name= "p1h2"
value={input.p1h2}
onChange={handleInput}
type= "number"
min="0">
</input>
<h2>Result sum: {result}</h2>
</div>
) }
CodePudding user response:
I've provided a working codesandbox for you to look at.
https://codesandbox.io/s/focused-pascal-ppyhz?file=/src/App.js:0-930
Good luck!