React Advanced

0% completed

Previous
Next
Displaying Pending State using useFormStatus

Displaying a pending state during form submission in React is a common practice to improve user experience by indicating that a process is in progress. This can be especially useful when submitting data to a server, as it helps inform users that the request is being processed and prevents them from submitting the form multiple times.

To achieve this, you can introduce a loading state in your component.

Displaying Pending State (Before useFormStatus)

In old React, you'd typically set the loading state to true when the form submission begins and then set it back to false once the request is completed (whether successful or failed). While the loading state is true, you can display a spinner, loading message, or disable the submit button to prevent further actions.

Here’s a simple example:

import React, { useState } from 'react'; import axios from 'axios'; function MyForm() { const [loading, setLoading] = useState(false); const [formData, setFormData] = useState({ name: '', email: '' }); const handleSubmit = (event) => { event.preventDefault(); setLoading(true); axios.post('/submit', formData) .then(response => { console.log('Form submitted successfully:', response); setLoading(false); // Reset loading state }) .catch(error => { console.error('Error submitting form:', error); setLoading(false); // Reset loading state }); }; return ( <form onSubmit={handleSubmit}> <input type="text" placeholder="Name" value={formData.name} onChange={(e) => setFormData({ ...formData, name: e.target.value })} /> <input type="email" placeholder="Email" value={formData.email} onChange={(e) => setFormData({ ...formData, email: e.target.value })} /> <button type="submit" disabled={loading}> {loading ? 'Submitting...' : 'Submit'} </button> </form> ); }

Here, the loading state is toggled based on the submission status of the form. This process is simplified with the introduction of the useFormStatus hook.

Introducing the useFormStatus Hook

The useFormStatus is a hook that gives you status information of the last form submission.

This can be represented as:

const { pending, data, method, action } = useFormStatus();

Here's what each part means:

  • pending: This variable represents a boolean value that indicates whether the form is currently being submitted (i.e., whether there is an ongoing process or the form is "pending"). It would typically be true while the form is submitting and false after the submission is complete.

  • data: This holds the result or response data related to the form submission, such as data returned from an API or server after the form has been successfully processed. If there is no active submission or no parent form, it will be null.

  • method: This represents whether the parent form is submitting with either a GET or POST HTTP method. By default, a form will use the GET method and can be specified by the method property.

  • action: Refers to the function passed to the action prop on the parent form. If there is no parent form, the property is null. If there is a URI value provided to the action prop, or no action prop specified, status.action will be null.

These variables are available for use in your component to track and handle the form's submission process.

Using the useFormStatus to Display Pending State During Form Submission

To display a pending state while a form is submitting, you can call the useFormStatus hook in a component rendered in a form and read the pending property returned.

Here, we use the pending property to indicate the form is submitting:

import { useFormStatus } from "react-dom"; function Submit() { const { pending } = useFormStatus(); return ( <button type="submit" disabled={pending}> {pending ? "Submitting..." : "Submit"} </button> ); } function Form({ action }) { return ( <form action={action}> <Submit /> </form> ); } export default function App() { return <Form action={submitForm} />; }

In this code example:

  • We import the useFormStatus from react-dom.
  • In the Submit function, we extract the pending property of the useFormStatus hook.
  • The pending property serves as state and displays a text that matches its current state.
  • A form component that accepts action as a prop is created. This components' action prop is assigned to the form’s action attribute.
  • The Submit component is rendered within the Form component, which handles the button for the submission of the form.
  • Finally, the Form component is returned in the App component with the submitForm function passed to the action prop.

NOTE: useFormStatus will not return status information for a form rendered in the same component. The useFormStatus Hook only returns status information for a parent form and not for any form rendered in the same component calling the Hook, or child components.

For instance, this would never work while using the useFormStatus hook.

function Form() { // pending will never be true const { pending } = useFormStatus(); return <form action={submit}></form>; }

useFormStatus does not track the form rendered in this component.

Instead, it should be called in the function whose action would be passed to the form:

function Submit() { const { pending } = useFormStatus(); return <button disabled={pending}>...</button>; }

This is the correct usage of the useFormStatus hook.

The useFormStatus hook is important because it provides status information about the last form submission, which can be used for various purposes, such as displaying a pending state during submission.

.....

.....

.....

Like the course? Get enrolled and start learning!
Previous
Next