Successful Submission in React Hook Form
A critical part of a form entry process is the submission of the form. This part of the process is always interesting when using a 3rd party library such as React Hook Form. One common fundamental task is letting the user know that the submission was successful. So, how do this in React Hook Form? Let’s find out.
An example
We have a simple form that has been implemented using React Hook Form. The form captures a users name:
type FormData = {
name: string;
};
export default function App() {
const { register, handleSubmit, errors } = useForm<FormData>();
const submitForm = async (data: FormData) => {
console.log("Submission starting", data);
const result = await postData(data);
console.log("Submitting complete", result.success);
};
return (
<div className="app">
<form onSubmit={handleSubmit(submitForm)}>
<div>
<input
ref={register({ required: true })}
type="text"
name="name"
placeholder="Enter your name"
/>
</div>
{errors.name && errors.name.type === "required" && (
<div className="error">You must enter your name</div>
)}
</form>
</div>
);
}
The name
field on the form is mandatory. We output a validation error if this hasn’t been populated, using the errors
object from React Hook Form.
The form submission logic calls a postData
function which sends the form to the server. Our mock implementation of postData
is below:
const postData = ({ name }: FormData): Promise<postDataResult<FormData>> => {
return new Promise((resolve) => {
setTimeout(() => {
console.log(`${name} saved.`);
resolve({ success: true });
}, 100);
});
};
This simulates a call to the server and returns that the submission was successful.
submitForm
is only invoked when validation passes
The forms validation checks fail if the user presses Enter in the name input before entering anything. In this case, our submitForm
function will not be invoked by React Hook Form. This means that the logic in submitForm
doesn’t need to check whether the form is valid - we can assume it is valid.
Nice!
Detecting when the form is being submitted
Typically we want to disable a form while the submission process is happening. React Hook Form has a handy formState
variable that contains whether the form is being submitted:
const {
register,
handleSubmit,
errors,
formState,} = useForm<FormData>();
We can use this to disable the input element while submission is happening:
<input
ref={register({
required: { value: true, message: "You must enter your name" }
})}
type="text"
name="name"
placeholder="Enter your name"
disabled={formState.isSubmitting}/>
We use the isSubmitting
variable within formState
to determine whether the form is being submitted and bind this to the input’s disabled
property.
It is important to note that when formState
changes, the form is rerendered.
When the submission is finished, isSubmitting
will be set to false
which means the input element becomes enabled again.
Detecting when the form has been submitted
We want to render a message to the user when the form has been successfully submitted. The formState
variable also contains a isSubmitted
variable. Let’s give this a try:
<form onSubmit={handleSubmit(submitForm)}>
...
{formState.isSubmitted && (
<div className="success">Form submitted successfully</div>
)}
</form>
So, we output a success message when isSubmitted
is true.
If the user presses Enter before filling in their name, we get the success message and the validation error:
Not quite what we require!
So, isSubmitted
only indicates whether the form has been submitted - not whether it was successfully submitted. This makes sense really because React Hook Form only controls part of the submission. For example, problems could happen on the server part of the submission that it doesn’t know about.
Detecting when the form has been successfully submitted
We need to create our own state for whether the form has been successfully submitted:
const [
isSuccessfullySubmitted,
setIsSuccessfullySubmitted,
] = React.useState(false);
The state is initialized to false
when the form is first loaded.
We set this state after the form has been posted to the server:
const submitForm = async (data: FormData) => {
console.log("Submission starting", data);
const result = await postData(data);
console.log("Submitting complete", result.success);
setIsSuccessfullySubmitted(result.success);};
We can then use isSuccessfullySubmitted
to render the success message:
{isSuccessfullySubmitted && (
<div className="success">Form submitted successfully</div>
)}
Now the success message doesn’t appear until the user has successfully submitted the form:
Cool!
We can also add isSuccessfullySubmitted
to the disabled
property binding on the input element, so that it is disabled when the form has been successfully submitted:
<input
...
disabled={formState.isSubmitting || isSuccessfullySubmitted}/>
You can see this working example in full in the CodeSandbox at https://codesandbox.io/s/react-hook-form-submission-state-c10md?file=/src/App.tsx
Wrap up
isSubmitted
in React Hook Form’s formState
indicates whether the form has been submitted and not necessarily whether it was successfully submitted. We use our own state to indicate successful submission, which we can set in our submission function.
Did you find this post useful?
Let me know by sharing it on Twitter.If you to learn more about using TypeScript with React, you may find my course useful: