Add or remove input fields dynamically with ReactJS

Today we will show you how to add or remove input fields dynamically with ReactJS. In a real project, sometimes you need to implement the dynamic form fields using React. So you will find the step by step instruction to create dynamic form.

Dynamically Adding Multiple Input Fields in React JS, How to implement a dynamic form with controlled components in React hooks, react native dynamically add input fields to form, add input field on click react, building a dynamic, controlled form with react, dynamically adding multiple input fields react, react add form field dynamically, react-dynamic-forms github, react dynamic form generation, react add component dynamically on click.

Here we will take an example, where we will display two input fields dynamically and also add two buttons to add and remove the fields.

Steps to implement dynamic input fields

  1. Create react application
  2. Design the form
  3. Implement logic to add/remove fields
  4. Output

1. Create react application

Let’s start by creating a simple react application with the help of the create-react-app. If you don’t know how to create a react application then refer to the link below.

Create React Application

2. Design the form

To design the form, we will add two inputs and two buttons into the form.

Our form should look like below.

Design Form - Add or remove input fields dynamically with ReactJS - Clue Mediator
Design Form – Add or remove input fields dynamically with ReactJS – Clue Mediator

3. Implement logic to add/remove fields

Now it’s time to write the logic. We will have three methods like input change, add button click and remove button click.

  1. handleInputChange – This method can be used on change of the input fields. In this method we need to update the value based on the given index.
  2. handleRemoveClick – Here we will remove elements from the list based on the index.
  3. handleAddClick – To add the new element in the list we have to call this method.

Let’s bind these methods with elements.

Write the above code together in one file and check the output.

App.js

4. Output

Output - Add or remove input fields dynamically with ReactJS - Clue Mediator
Output – Add or remove input fields dynamically with ReactJS – Clue Mediator

That’s it for today.
Thank you for reading. Happy Coding!

Demo & Source Code

Github Repository StackBlitz Project
If you found value in this article,
you can support us by buying me a coffee! ☕

You may also like...

57 Responses

  1. Emmanuel Obiajuru says:

    Really great dynamic form but i want to ask what i have to update or edit the data passed in by the form, how do i display it with the number of dynamic input that the data was first created with in the first place.

    • Clue Mediator says:

      Hi Emmanuel,
      We are glad you liked it.

      We are a little bit confused about your query. Can you please elaborate on it?

      Subscribe us for weekly updates or like and follow us for regular updates.

  2. Emmanuel Obiajuru says:

    I used the form to pass in data into my database but i would also like to edit the said data using the same form. now if i have multiple dynamic input data to display how would i do it.

    • Clue Mediator says:

      Hello Emmanuel,
      In the edit mode, you have to simply set the value of the inputList state variable in the same data structure.

      Suppose, if you have added dynamic input data (i.e. 3 records) into the database then use the same 3 records to assign into the inputList while performing the edit operation.

      Like, your inputList should be the same as the below in edit mode and the dynamic form will automatically render in DOM.
      [
      { "firstName":"John", "lastName":"Martin" },
      { "firstName":"Michael", "lastName":"Smith" },
      { "firstName":"James", "lastName":"Palmer" }
      ]

      I Hope, your doubts will be clear now.
      Let us know if you have any queries.

      • Vivek says:

        Awesome solution but what if there are not text input but have drop-down. Then how we handle it and how will populate data. E.g.
        1Drop-down , 2 drop-down, 3 p-tag(but have to save value in state) , 4th drop-down.

        On the base of 2nd(dd) 3-4 show and hide. And in 3-4, there can be any type of inputs or single value.

        I was trying like that and it was not working.

        • Clue Mediator says:

          Hi Vivek,
          Can you please share your example using the StackBlitz link? We will be happy to help you!

  3. Dinesh says:

    Hi, Great explanation.. Thanks.. It would be great to know, is there a way to add ref’s to these dynamic input so that i can focus when the input box is added..?

  4. Bruno says:

    Very good! Congratulations! =)

  5. zatin says:

    Thanks a lot. No explanation could be better than this. such a great work.

  6. lIllI says:

    Thank you for a great post. I have a question tho

    const list = […inputList];
    list[index][name] = value;

    console.log(list[0] === inputList[0]) -> true

    Since […inputList] is a shallow copy of inputList,
    isn’t this changing the state directly without hook like setState?

    • Clue Mediator says:

      In this case, it will also update the state variable because we are not doing the deep clone (For deep clone we can use the lodash library or use some other method). But I will suggest you to use the setState to rerender the DOM elements.

  7. Armon says:

    You are a god send. Thank you so much.

  8. Aman says:

    Hi
    Really good example. Thanks for the post.
    I am very new in react. I tried to add a dropdown selection input with other inputs. Unfortunately, it didn’t work. In my case, it failed to get the value of the selected item. Have you tried that?

  9. Andres Patiño says:

    Hello! very good example for people like me that are learning React, like Aman I’ve been trying to adapt the this tutorial but with dropdown elements that have mapped options from another list(each option value is ”codSede” and each option label is ”sede”) :

    let sedesList = [
    { codSede: 1, sede: “Claustro” },
    { codSede: 2, sede: “Molinos” },
    { codSede: 3, sede: “Ciudad Torre Uno” },
    ]

    , the goal is to change the state of inputList fields:

    const [inputList, setInputList] = useState([{ codSede: 0, sede: “” }])

    for the value and name of the selected option in each dropdown, but I havent had any luck so far, any suggestions would be greatly appreciated.

    Again thanks for the awesome tutorial

  10. Mike says:

    Hello, how I can use this code: const [inputList, setInputList] = useState([{ firstName: “”, lastName: “” }]); without useState? Because I used old react. Thanks

    • Clue Mediator says:

      Hi Mike,
      You have to declare your state variable like this…

      // state variable
      this.state = {
      inputList: [{ firstName: "", lastName: "" }]
      };

      // change event
      const { name, value } = e.target;
      const list = [...inputList];
      list[index][name] = value;
      this.setState({ inputList: list });

      • Mike says:

        Thanks. How I can use or change setInputList(list) ?

        For example:

        const handleRemoveClick = index => {
        const list = […inputList];
        list.splice(index, 1);
        setInputList(list);
        };

        const handleAddClick = () => {
        setInputList([…inputList, { firstName: “”, lastName: “” }]);
        };

        • Clue Mediator says:

          Use it like this…

          const handleRemoveClick = index => {
          const list = [...this.state.inputList];
          list.splice(index, 1);
          this.setState({ inputList: list });
          };

          const handleAddClick = () => {
          this.setState({ inputList: [...this.state.inputList, { firstName: "", lastName: "" }] });
          };

  11. Mike says:

    I have error:

    Violation: Video.render(): A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object.

    my render

    render: function() {
    {
    this.state.inputList.map((x, i) => {
    return (

    handleInputChange(e, i)}
    />
    handleInputChange(e, i)}
    />

    {this.state.inputList.length !== 1 && handleRemoveClick(i)}>Remove}
    {this.state.inputList.length – 1 === i && Add}

    );
    })
    }
    }

  12. Mike says:

    Hi. Parse error: this.setState({ inputList: […this.state.inputList, { firstName: “”, lastName: “” }] });

    here error […this.state.inputList, { firstName: “”, lastName: “” }]

  13. Raf says:

    A default input appears, how could we make no input appear by default? Thanks!!

  14. Toufik says:

    First of all, the tutorials you provide are excellent, short and concise.

    Regarding this it’s working, but adding a new input doesn’t seem to work properly instead it is just copying the value in all the array of the object.
    I setup a Stackblitz for you to understand better: https://stackblitz.com/edit/react-dm6jwd?file=src%2FApp.js

    I hope you can help me !:)

    Thank you anyway!

    • Clue Mediator says:

      Your Add button click logic is wrong. Please try to update it as below.

      setinstance([...instance, { Country: "", Answer: "" }]);

      I Hope, This will work for you!

  15. sandeep says:

    thanks for a great tutorial, I want to ask something
    what if we want to add different types of the input field like image and text dynamically, we have more than one type of add button so we can add the next input by choice it can be image or text or heading like you created this page in the different post you add different no. of images different no. text and heading dynamically
    please ans me

    • Clue Mediator says:

      Hi Sandeep, You can add any number of the field. You have to simply manage it as an input field. If you are adding an image then you can use image src in the array.

  16. Valentin says:

    Interesting approach! How would you apply this to a WordPress Gutenberg block?

  17. Sucheta says:

    Hi..great article!!!
    I am having an issue on handleRemoveClick()
    The ‘list’ is getting updated but in setInputList(list) not setting the updated values.
    setInputList(list) – is one step behind (It is updated in the next remove click)
    why is this happening and how can i solve it?
    Thanks in advance.

    • Clue Mediator says:

      Hi Sucheta,
      You can not setState is an asynchronous method. So you can not immediately get the updated result in the next execution. Please try to compare your code with GitHub or StackBlitz demo. You will find the source link at the end of the article.

  18. JonnyJ says:

    This is really excellent, thanks. I am trying to impliment it with React Hook Form and not getting very far. Any change of a new tutorial with React Hook Form? 🙂

  19. Taha Latief says:

    Hi there,
    I tried to add a submit button at the bottom and log the inputList but i am getting the error : “TypeError: Cannot read property ‘projectType’ of null”.
    Can advise me on what i am doing wrong?
    Thanks.

    • Clue Mediator says:

      Hi Taha,
      Make sure you should have a value in object/array before reading the property ‘projectType’. Is it possible to share your code via StackBlitz? You can also compare your code with GitHub/StackBlitz code.

  20. Rohit Gautam says:

    That is really nice of you to share your experience.
    helped me ,

    Thank you very much

  21. Grey says:

    Thanks for best article. But I get eslint error – use callback in setState when referencing the previous state – in code const list = […this.state.inputList]; please guide
    Thanks!

  22. Khajan Chandra says:

    Hello, how I can use this code as const [winningTiers, setWinningTiers] = useState([{tier_wallet_type: “”, rank_from: “”, rank_to: “”, distribution: “”}])

    rank_from: 1 , rank_to: 1
    rank_from: 2, rank_to: 10
    rank_from: 11, rank_to: 50

    i just want to update the input value greater then previous rank. kindly do the needful.

  23. Eugene says:

    hello, i have a problem with the event handler when i make the eventHandler always error Element implicitly has an ‘any’ type because expression of type ‘any’ can’t be used to index type ‘{ name: string; email: string; }’ like this

Leave a Reply

Your email address will not be published. Required fields are marked *