I started to learn to react today, and I'm trying to build a super simple calculator, but I'm not familiar with the syntax and basics of reacting yet. No matter how much I'm looking and reading, my code is like this : import './App.css';
const plusaction = (a, b) => {
alert(a+b);
}
function App() {
return (
<div className="App">
<input type="number" value={plusaction.a}></input>
<input type="number" value={plusaction.b}></input>
<button onClick={plusaction}>Result</button>
</div>
);
}
export default App;
As you can see, it was supposed to be a simple form plus action calculator, but the alert brought me "object undefined", Would you mind fixing my code and explaining what I did wrong? I appreciate any help you can provide.
First you must have a state to save data
after that, you must change your state with onChange function of input
after that, you must read your values from state
function App() {
const [state, setState] = useState({ a: 0, b: 0 });
const plusaction = () => {
alert(state.a + state.b);
};
return (
<div className="App">
<input type="number" value={state.a} onChange={(e) => setState({ ...state, a: e.target.value })} />
<input type="number" value={state.b} onChange={(e) => setState({ ...state, b: e.target.value })} />
<button onClick={plusaction}>Result</button>
</div>
);
}
export default App;
Ideally you want to want to store your input values in state. Here I've initialised the input state as an object which will later update with a and b properties containing the values of the inputs.
plusAction (or handleAdd as I've called it here) then just takes the a and b values from the input state and logs the sum to the console.
Give you input elements a name attribute so they can be identified easily.
const { useState } = React;
function Example() {
// Initialise state
const [ input, setInput ] = useState({});
// Destructure the a and b properties from
// the state and sum them
function handleAdd() {
const { a, b } = input;
console.log(a + b);
}
// The onChange listener is attached to the
// parent container so we need to check to see
// if the changed element is an input
function handleChange(e) {
if (e.target.matches('input')) {
// Destructure the name and value from the input
const { name, value } = e.target;
// Set the new input state by copying it, and
// updating either the a or b property we get from
// the name attribute, and then setting its value
// Note: the type of the value from an input will
// always be a string, so you need to coerce it to
// a number first
setInput({ ...input, [name]: Number(value) });
}
}
// The input elements store the value of the
// corresponding state property
return (
<div onChange={handleChange}>
<input name="a" type="number" value={input.a} />
<input name="b" type="number" value={input.b} />
<button onClick={handleAdd}>Result</button>
</div>
);
}
ReactDOM.render(
<Example />,
document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Additional documentation
You should use useRef to do this. It will more efficient than useState which will re-render your app each time your number change.
import { useRef } from "react";
function App() {
const a = useRef(0);
const b = useRef(0);
const plusaction = () => {
console.log(a.current.value);
console.log(b.current.value);
alert(parseInt(a.current.value) + parseInt(b.current.value));
};
return (
<div className="App">
<input type="number" ref={a} />
<input type="number" ref={b} />
<button onClick={plusaction}>Result</button>
</div>
);
}
export default App;