React Hook Form
FormHooksReact
react-hook-from
// https://github.com/react-hook-form/react-hook-form
import React, {ChangeEvent} from 'react';
import {useForm} from 'react-hook-form';
function App() {
const {
register,
handleSubmit,
formState: {errors},
} = useForm();
const onSubmit = (data) => console.log(data);
// use with jsx <input onChange={changeUpdate} />
function changeUpdate(e: ChangeEvent<HtmlInputElement>) {
setCount(+e.target.value);
}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('firstName')} /> {/* register an input */}
<input {...register('lastName', {required: true})} />
{errors.lastName && <p>Last name is required.</p>}
<input {...register('age', {pattern: /\d+/})} />
{errors.age && <p>Please enter number for age.</p>}
<input type="submit" />
</form>
);
}
Normal Form
Controlled Form
// For complex nested update: https: //github.com/immerjs/use-immer
import {useState, ChangeEvent} from 'react';
export default function ControlledForm() {
const [person, setPerson] = useState({
firstName: 'Derek',
lastName: 'Wang',
email: 'derekw@sculpture.com',
isSoldier: false,
});
function handleChange(e: ChangeEvent<HTMLInputElement>) {
const value = e.target.type === 'checkbox' ? e.target.checked : e.target.value;
setPerson({
...person,
[e.target.name]: value,
});
}
function handleSubmit() {
// use person state
}
return (
<form onSubmit={handleSubmit}>
<label>
First name:
<input name="firstName" type="text" value={person.firstName} onChange={handleChange} />
</label>
<label>
Last name:
<input name="lastName" type="text" value={person.lastName} onChange={handleChange} />
</label>
<label>
Email:
<input name="email" type="text" value={person.email} onChange={handleChange} />
</label>
<label>
isSoldier:
<input name="isSoldier" type="checkbox" value={person.isSoldier} onChange={handleChange} />
</label>
<p>
{person.firstName} {person.lastName} ({person.email})
</p>
<button type="submit">Submit</button>
</form>
);
}
Uncontrolled Form
This is useful especially when the form controls are returned by a GET response. e.g. some checkboxes' values are not known at build time.
export function getFormData(e: React.FormEvent<HTMLFormElement>) {
const formData: {[key: string]: any} = {};
(Array.from((e.target as HTMLFormElement).elements) as HTMLFormElement[]).forEach((e) => {
if (!e.name) {
return;
}
// normal html input
if (e.getAttribute('type') !== 'checkbox') {
formData[e.name] = e.value;
return;
}
// save checkbox checked values
if (e.checked) {
e.name in formData ? formData[e.name].push(e.value) : (formData[e.name] = [e.value]);
}
});
return formData;
}
// For complex nested update: https: //github.com/immerjs/use-immer
import {FormEvent} from 'react';
export default function UncontrolledForm() {
handleSubmit = (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
// way 1
const firstName = event.target.firstName.value;
const lastName = event.target.lastName.value;
// way 2:
const formData: any = {};
(Array.from(event.currentTarget.elements) as HTMLFormElement[]).forEach((e) => {
if (e.name) {
formData[e.name] = e.value;
}
});
// Here we do something with form data
console.log(firstName, lastName);
};
return (
<form onSubmit={handleSubmit}>
<label>
First name:
<input name="firstName" type="text" />
</label>
<label>
Last name:
<input name="lastName" type="text" />
</label>
<label>
Email:
<input name="email" type="text" />
</label>
<label>
isSoldier:
<input name="isSoldier" type="checkbox" />
</label>
<button type="submit">Submit</button>
</form>
);
}