Let the name handle the input
Sun Oct 09 2022
A simple spell but quite unbreakable
When you need to handle multiple controlled input elements, you can add a name attribute to each element and let the handler function choose what to do based on the value of event.target.name.
In the example below you can see we just have one function to handle the input change because we determine what input value requires to be updated base on the property name
of it.
class Reservation extends React.Component {
constructor(props) {
super(props);
this.state = {
isGoing: true,
numberOfGuests: 2,
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value =
target.type === "checkbox" ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value,
});
}
render() {
return (
<form>
<label>
Is going:
<input
name="isGoing"
type="checkbox"
checked={this.state.isGoing}
onChange={this.handleInputChange}
/>
</label>
<br />
<label>
Number of guests:
<input
name="numberOfGuests"
type="number"
value={this.state.numberOfGuests}
onChange={this.handleInputChange}
/>
</label>
</form>
);
}
}
In functional components you can make a custom hook that does the same:
import { useState } from "react";
export const useForm = (initialState = {}) => {
const [values, setValues] = useState(initialState);
const reset = () => {
setValues(initialState);
};
const handleInputChange = ({ target }) => {
setValues({
...values,
[target.name]: target.value,
});
};
return [values, handleInputChange, reset];
};