Creating a React Form Repeater Component: A Step-by-Step Guide
Tags: react, beginners, webdev, nextjs
Published: 2023-08-07 17:06:04

## Introduction

In this tutorial, we will guide you through the process of creating a dynamic Next.js Form Repeater component using Next.js with the support of Tailwind CSS.
We're using Next.js as a React framework, but you can choose the one you want.
I encourage you to follow [React's recommendations](https://react.dev/learn/start-a-new-react-project)

This article is an extension of this one:

{% embed https://dev.to/leandro_nnz/creating-a-vue-3-form-repeater-component-a-step-by-step-guide-4ji6 %}

I experienced the need of building one component like this one in a Vue project. This is the same tutorial with the same functionality, but for React. 

This tutorial was written following the needs in the above article. 
As example, we're creating a multi-destination dynamic form.

By leveraging the latest version of Next.js and the utility-first approach of Tailwind CSS, we can build an intuitive and responsive form repeater that enhances the user experience.

### 1. Set Up Your Next.js Project
To get started, ensure you have Node.js installed on your machine. 
You can create a new Next.js project using the following commands in your terminal:

```bash
npx create-next-app next-form-repeater
cd next-form-repeater
```

### 2. Install and Set Up Tailwind CSS
Next, install Tailwind CSS and its peer dependencies:

```bash
npm install tailwindcss@latest postcss@latest autoprefixer@latest
```

Create a `tailwind.config.js` file in the root of your project with the following content:

```javascript
module.exports = {
  mode: 'jit',
  purge: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
  darkMode: false,
  theme: {
    extend: {},
  },
  variants: {},
  plugins: [],
};
```

Update the `styles/globals.css` file to use Tailwind CSS:

```css
/* styles/globals.css */
@import 'tailwindcss/tailwind.css';
```

### 3 Create the Form Repeater Component
Inside the "components" folder of your project, create a new file called "FormRepeater.js". 
This file will contain the definition of our custom Form Repeater component.

```jsx
import { useState } from 'react';

const FormRepeater = () => {
  const [fields, setFields] = useState([{ value: '' }]);

  const addField = () => {
    setFields([...fields, { value: '' }]);
  };

  const removeField = () => {
    if (fields.length > 1) {
      setFields(fields.slice(0, -1));
    }
  };

  const onSubmit = () => {
    const formData = {};
    fields.forEach((field, index) => {
      formData[`Destination ${index + 1}`] = field.value;
    });

    // Your submit logic here (e.g., sending the formData to the server or handling it as needed)
    // For demonstration purposes, we'll log the form data to the console.
    console.log('Form data:', formData);
  };

  return (
    <div>
      {fields.map((field, index) => (
        <div key={index}>
          <input
            type="text"
            value={field.value}
            placeholder={`Destination ${index + 1}`}
            onChange={(e) => {
              const updatedFields = [...fields];
              updatedFields[index].value = e.target.value;
              setFields(updatedFields);
            }}
            className="border rounded p-2 mb-2"
          />
        </div>
      ))}
      <button onClick={addField} className="bg-blue-500 text-white px-4 py-2 rounded mr-2">
        Add Destination
      </button>
      <button onClick={removeField} className="bg-red-500 text-white px-4 py-2 rounded">
        Remove Destination
      </button>
      <button onClick={onSubmit} className="bg-green-500 text-white px-4 py-2 rounded mt-4">
        Submit
      </button>
    </div>
  );
};

export default FormRepeater;
```

### 4. Using the Form Repeater Component
In your main app file (e.g., "pages/index.js"), import and use the Form Repeater component as follows:

```jsx
import FormRepeater from '../components/FormRepeater';

export default function Home() {
  return (
    <div>
      <h1 className="text-3xl font-bold mb-4">Travel Reservations</h1>
      <FormRepeater />
    </div>
  );
}
```

### 5. Run Your Next.js App
With everything set up, you can now start your Next.js app and see the Form Repeater in action:

```bash
npm run dev
```

### 6. Styling the Form Repeater
To add some basic styling to the Form Repeater component, we'll use Tailwind CSS classes. 
Open the "FormRepeater.js" file and update the class names for the buttons and inputs to apply styling:

```jsx
// ...
const FormRepeater = () => {
  // ...

  return (
    <div>
      {fields.map((field, index) => (
        <div key={index}>
          <input
            type="text"
            value={field.value}
            placeholder={`Destination ${index + 1}`}
            onChange={(e) => {
              const updatedFields = [...fields];
              updatedFields[index].value = e.target.value;
              setFields(updatedFields);
            }}
            className="border rounded p-2 mb-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
          />
        </div>
      ))}
      <button onClick={addField} className="bg-blue-500 text-white px-4 py-2 rounded mr-2 hover:bg-blue-600">
        Add Destination
      </button>
      <button onClick={removeField} className="bg-red-500 text-white px-4 py-2 rounded hover:bg-red-600">
        Remove Destination
      </button>
      <button onClick={onSubmit} className="bg-green-500 text-white px-4 py-2 rounded mt-4 hover:bg-green-600">
        Submit
      </button>
    </div>
  );
};

export default FormRepeater;
```

### 7. Testing the Form Repeater
Now that you've added some styling, you can run your Next.js app again and test the Form Repeater component. 
Open your browser and visit [http://localhost:3000](http://localhost:3000) to interact with the Form Repeater.

### Step 8: Handling Form Submission
To handle form submission, we've already implemented the `onSubmit` function in the "FormRepeater.js" file. 
Currently, the function logs the form data to the console. 
You can replace this with your desired form submission logic, such as sending the form data to a server or storing it in a database.

## Conclusion
Congratulations! 

You've successfully built a dynamic Form Repeater component using Next.js with the support of Tailwind CSS.

By combining the latest version of Next.js and the utility-first approach of Tailwind CSS, you've created an intuitive and responsive form repeater that enhances the user experience.

**References**
- Next.js documentation: [https://nextjs.org/docs](https://nextjs.org/docs)
- Tailwind CSS documentation: [https://tailwindcss.com/docs](https://tailwindcss.com/docs)

Thanks for reading!