Blog

Handling Form Loading States in Next.js/React (2024)

Ryan Gan
Ryan GanPublished on Jun 23, 2024

5 Ways to Handle Form Loading States in Your Next.js/React App: From Basic to Advanced

When building forms in modern web applications, handling loading states effectively is crucial for providing a smooth user experience.

In this article, I will cover five different methods to manage form loading states in a Next.js/React application and discuss their use cases and benefits with examples.

This includes leveraging hooks like , , and to enhance your forms for better performance and user experience.

Method 1: Local Component State

The first method is using local component state with . It is straightforward and works well for simple forms to provide immediate feedback.

Pros:

  • Easy to implement
  • No additional dependencies

Cons:

  • Extra and variables can lead to repetitive code
  • Difficult to manage with multiple forms in larger application

Use cases:

  • Ideal for applications with limited number of simple forms

Example:

Method 2: formState data in React Hook Form

The second method is only available if you’re using React Hook Form for handling forms. I highly recommend using it for dealing with forms in React applications. It abstracts away the process of manually handling the state of each field, removes the unnecessary re-renders when there are changes in form values, and provides a comprehensive form state management solution out of the box.

Pros:

  • Reduces boilerplate code, simplifies state magamenet
  • Form state management out of the box, including , ,
  • Optimizes performance using uncontrolled components to reduce unnecessary re-renders

Cons:

-May be challenging when integrating with some advanced React hooks like and as they require using form submission through attribute instead of the handler

  • Not the best solution for controlled components like Formik (This isn’t a con regarding form state handling, just React Hook Form as a form solution in general)

Use cases:

  • Suitable for almost any size of applications with any number of forms

Example:

Method 3: useTransition Hook

The hook is not specifically designed for handling form loading state, but it could be a great alternative when the form submission take longer. It ensures the UI remains responsive during these operations by allowing lower-priority updates to be deferred until high-priority tasks are completed.

The hook does not take any parameters and returns an array containing an flag and a function. The flag indicates whether the transition is in progress, while the function allows you to mark a state update as a low-priority operation.

Pros:

  • Prevents UI blocking during longer form submission

Cons:

  • Overkill for simple forms and adds a layer of complexity

Use cases:

  • Ideal for forms where the submission might take a long time, such as file uploading, allowing users to interact with the UI while waiting

Example:

In the example, we wrap the API call within the function. This ensures that the submission state is captured by the flag. Additionally, a statement is added after the function call. This line will execute first because the operations inside are marked as lower priority, allowing higher priority updates to complete first.

Note: The hooks introduced in the following section are available only in Next.js and the experimental version of React. The examples provided will be part of a Next.js app.

Method 4: useFormStatus Hook

The hook is designed to provide status information about the last form submission. It can be used to display the submission state of the form, the data being submitted, the HTTP method, and the action function. These details are returned in a status object by the hook, as shown in the example below:

One important thing to note is that the hook must be defined within a child component of the element. This child component can be nested within any form.

Pros:

  • Promotes reusability of form’s child components

Cons:

  • Limited scope as components that need to be at the same level as the parent component won't have access to the state information

Use cases:

  • Ideal for applications with multiple forms sharing the same components where only the pending states are of interest

Example:

Method 5: useActionState Hook

The hook could be the most powerful tool for handling form submissions in a Next.js app. It allows you to attach state to an action, send it to the server, and receive a state with the action's response while having insight into the action's state.

The hook takes two parameters: a server action and the initial state of that action. It returns an array of three values: the state received from the action’s response, the action function to be used in the form’s attribute, and an flag that captures the form's submission state. To complete the setup, the server action needs to accept as the first parameter and include the state in its return value. Below is an example setup.

Pros:

  • Allows attaching state to an action
  • Keeps states at the top level, making them accessible by all components
  • Progressively enhanced, meaning form submission works even if JavaScript is disabled

Cons:

  • Might be harder to understand at initially
  • Potential redundant setup, useActionState enforces a initialState parameter in the initiation and a prevState parameter in the server action function that might not be used

Use cases:

  • Suitable for almost all scenarios if additional setup is not an issue.

Example:

In this example, we attach an initial state object containing an empty message value and send it with the action. The state is used to track the form submission status. When the server action is completed, it returns a state with the response containing a success message.

The server action looks like:

Lastly

I hope this article helps you better understand form submission in Next.js/React applications. These insights are based on my previous experience working with forms. If you have any questions or notice any inaccuracies, please feel free to leave a comment!

Thanks for Reading and Happy Coding!