0
0
NextjsHow-ToBeginner · 4 min read

How to Use useFormState in Next.js for Form Handling

In Next.js, you can use the useFormState hook to track and manage form input values and validation states easily. It provides a simple way to handle form data reactively inside functional components without extra boilerplate. Just import useFormState, initialize it with your form fields, and use the returned state and handlers in your form elements.
📐

Syntax

The useFormState hook is used to create and manage form state in a React or Next.js component. It returns an array containing the current form state object and an object of input bindings helpers.

Basic usage pattern:

  • const [formState, { text }] = useFormState(initialValues);
  • formState.values holds current form input values.
  • formState.setValues updates form values.
  • formState.errors holds validation error messages.
  • formState.setErrors updates error messages.
jsx
import { useFormState } from 'react-use-form-state';

function MyForm() {
  const [formState, { text }] = useFormState({
    name: '',
    email: ''
  });

  return (
    <form>
      <input {...text('name')} placeholder="Name" />
      <input {...text('email')} placeholder="Email" />
    </form>
  );
}
💻

Example

This example shows a simple Next.js functional component using useFormState to manage a form with name and email fields. It updates the form state on input changes and logs the values on submit.

jsx
import React from 'react';
import { useFormState } from 'react-use-form-state';

export default function ContactForm() {
  const [formState, { text }] = useFormState({
    name: '',
    email: ''
  });

  function handleSubmit(event) {
    event.preventDefault();
    console.log('Form submitted:', formState.values);
  }

  return (
    <main>
      <h1>Contact Us</h1>
      <form onSubmit={handleSubmit}>
        <label htmlFor="name">Name:</label>
        <input id="name" {...text('name')} placeholder="Your name" required />

        <label htmlFor="email">Email:</label>
        <input id="email" {...text('email')} placeholder="Your email" type="email" required />

        <button type="submit">Send</button>
      </form>
    </main>
  );
}
Output
Rendered form with two input fields (Name, Email) and a Send button. On submit, logs form values to the console.
⚠️

Common Pitfalls

Common mistakes when using useFormState include:

  • Not spreading the input props returned by the hook, which breaks input binding.
  • Forgetting to prevent default form submission behavior, causing page reload.
  • Not initializing all form fields in useFormState, leading to uncontrolled inputs.
  • Ignoring accessibility by missing label elements linked to inputs.

Correct usage ensures inputs update state and form submits without reload.

jsx
/* Wrong way: Missing spread operator on input props */
<input id="name" value={formState.values.name} onChange={formState.setValues} />

/* Right way: Spread input props from useFormState */
<input id="name" {...text('name')} />
📊

Quick Reference

FeatureDescription
useFormState(initialValues)Initialize form state with default values.
formState.valuesCurrent values of all form fields.
formState.setValuesFunction to update form values.
inputProps = text('fieldName')Returns props to bind text input to form state.
handleSubmit(event)Prevent default and handle form submission.

Key Takeaways

Use useFormState to easily manage form inputs and state in Next.js functional components.
Always spread the input props returned by useFormState on your form elements for proper binding.
Initialize all form fields in useFormState to avoid uncontrolled input warnings.
Prevent default form submission to handle data without page reload.
Use labels linked to inputs for better accessibility.