No need to write change handlers for multiple React inputs! You can create a function that takes both the prop name and the value as arguments. If using Typescript, use generics to narrow the type of the value based on the prop.
type User = {
name: string;
age: number;
admin: boolean;
};
function App() {
const [user, setUser] = useState<User>(defaultUser);
const setUserProp = <P extends keyof User>(prop: P, value: User[P]) => {
setUser({ ...user, [prop]: value });
};
return (
<div>
<input
onChange={e => {
setUserProp("name", e.target.value);
}}
></input>
<input
onChange={e => {
setUserProp("age", parseInt(e.target.value));
}}
></input>
<input
onChange={() => {
setUserProp("admin", !user.admin);
}}
></input>
</div>
);
}
export default App;
Top comments (6)
I often further simplify this by giving the
<input>
elements a name property & then using the followingFor the cases when you don't need current input state for validation, calculation, e.t.c you just can use uncontrolled inputs and read inputs' values via
ref
.Awesome! I do think this will end up with type errors for varied types of object properties (e.g., numbers and booleans)
Of course, this was just a minimal example. When I use this properly in my Typescript projects I include typeguards etc. to ensure state types remain consistent.
Nice use of generics here with keyOf, will use going forward.
That's so simple, so useful. Thanks!