Forms

The Form component from the @remix-run/react library is a high-level component that provides a declarative way to create accessible HTML forms that work well with the Remix framework. In this documentation, we will go over the key features of the Form component and how to use them.

Basic Usage

To use the Form component, you need to import it from the @remix-run/react library and wrap your form elements inside it. Here's an example:

import { Form } from "@remix-run/react";

function MyForm() {
  return (
    <Form method="post">
      <label>
        Name:
        <input type="text" name="name" />
      </label>
      <button type="submit">Submit</button>
    </Form>
  );
}

In the example above, we're using the Form component to create a simple form with a single input field for the user's name.

Handling Form Submissions

When the user submits a form, the Form component will automatically intercept the submission and prevent the default behavior of the browser. It will then make a request to the server using the fetch API with the method and action values passed to the Form component as options.

To handle the form submission on the server side, you need to define a route handler in your Remix app that matches the action value passed to the Form component. Here's an example:


export const action: ActionFunction = async ({ request, params }) => {
  const fd = await request.formData();
  const name = fd.get("name")?.toString();
  
  console.log(name);

  return redirect("/home");
};

In the example above, we're using the request.formData() method to parse the form data sent by the client. We're then extracting the value of the name field and logging it to the console. Finally, we're returning a redirect response to take the user back to the homepage.

Form Validation

The Form component provides a declarative way to perform client-side form validation using the required and pattern attributes of the form fields. Here's an example:

<Form method="post">
  <label>
    Name:
    <input type="text" name="name" required />
  </label>
  <label>
    Email:
    <input type="email" name="email" required pattern=".+@.+\..+" />
  </label>
  <button type="submit">Submit</button>
</Form>

In the example above, we're using the required attribute to make both the name and email fields required. We're also using the pattern attribute to specify a regular expression that the email field must match.

If the user submits the form without filling out the required fields or with invalid data, the Form component will prevent the submission and display error messages next to the invalid fields.

Customizing Form Behavior

The Form component provides several props that allow you to customize its behavior. Here's a list of the most important props:

onSubmit

The onSubmit prop allows you to define a function that will be called when the user submits the form. This function will be called before the default form submission behavior is executed. You can use this function to perform additional validation or to modify the form data before it is sent to the server.

Here's an example:

function handleFormSubmit(formData) {
  console.log(`Received form submission: ${formData.get("name")}`);
}

<Form method="post" action="/submit" onSubmit={handleFormSubmit}>
  <label>
    Name:
    <input type="text" name="name" required />
  </label>
  <label>
    Email:
    <input type="email" name="email" required pattern=".+@.+\..+" />
  </label>
  <button type="submit">Submit</button>
</Form>

In the example above, we're passing a handleFormSubmit function to the onSubmit prop of the Form component. This function will be called with the form data as its only argument when the user submits the form.

enctype

The enctype prop allows you to specify the encoding type of the form data when it is sent to the server. The default value is application/x-www-form-urlencoded, which is the standard encoding type for HTML forms. You can also use multipart/form-data if you need to upload files as part of the form submission.

Here's an example:

<Form method="post" enctype="multipart/form-data">
  <label>
    Name:
    <input type="text" name="name" required />
  </label>
  <label>
    Photo:
    <input type="file" name="photo" />
  </label>
  <button type="submit">Submit</button>
</Form>

In the example above, we're using the enctype prop to specify multipart/form-data, which allows us to upload files as part of the form submission.

className

The className prop allows you to specify a CSS class name for the form element that is rendered by the Form component. This can be useful if you need to style the form using CSS.

Here's an example:

<Form method="post" action="/submit" className="my-form">
  <label>
    Name:
    <input type="text" name="name" required />
  </label>
  <label>
    Email:
    <input type="email" name="email" required pattern=".+@.+\..+" />
  </label>
  <button type="submit">Submit</button>
</Form>

In the example above, we're using the className prop to add a my-form class to the form element. This class can be used in a CSS stylesheet to style the form.

Conclusion

The Form component from the @remix-run/react library provides a convenient and declarative way to create accessible HTML forms that work well with the Remix framework. By using this component, you can easily handle form submissions on the server side and perform client-side form validation. Additionally, the Form component provides several props that allow you to customize its behavior and appearance.

Last updated