React Forms : How to make input data as list objects with same input name?

2.6k views Asked by At

I'm Posting input data to API's where the API's structure as array list with n objects.

Problem: The problem I'm facing is while handling the change, i'm replacing the data instead of inserting as an another object.

My code as follows:

the objects in the list is dynamic not limited to two

in Constructor->

this.state={
formData: [
        {
          information: "",
          from: "",
          to: "",
        },
        {
          information: "",
          from: "",
          to: "",
        },
      ],
}

handling the Change as follow:

handleChange = (e) => {
    const { name, value } = e.target;
    const { formData} = this.state;
    this.setState({
        formData: {
          ...formData,
          [name]: value,
        },
      });

Handle submit:

handleSubmit = (e) => {
    e.preventDefault();
    console.log(this.state.formData);
    }

Form fields as follows:

<form onSubmit={this.handleSubmit}>
<div>
 <input  type="text"   name="information"   onChange={this.handleChange}   />
 <input  type="text"   name="from"          onChange={this.handleChange}   />
 <input  type="text"   name="to"            onChange={this.handleChange}   />
</div>
<div>
 <input  type="text"   name="information"   onChange={this.handleChange}   />
 <input  type="text"   name="from"          onChange={this.handleChange}   />
 <input  type="text"   name="to"            onChange={this.handleChange}   />
</div>
.
.
.
<button> + Add new Set (div) </button>
<button type="submit"> Submit </button>
</form>

I'm aware that mistake is handing logic but i tried lot to correct. Please help me out.

Edit: Expected output:

 [
        {                    
            "information": "info  1",
            "from": 1,
            "to": 50
        },
        {                    
            "information": "info  2",
            "from": 51,
            "to": 80
        },
        {
            "information": "info  3",
            "from": 81,
            "to": 100
        }
    ]
3

There are 3 answers

0
elMeroMero On

If you want to insert a third object to formData you need to add curly brackets {} to frame [name]:value as an object. Also formData is an Array so it must be with square brackets not curly ones.

this.setState({
        formData: [
          ...formData,
          { [name]: value }
        ],
0
Victor Barros On

The best approach is to use prevState in setState.

this.setState(prevState => ({...prevState, [name]: value }))

This will guarantee that you always use the previous state. setState is an async function, if you use formData it will not guarantee that the changes that you already dispatch are in place to be used.

0
Jinen Abdelhak On
state={
formData: [
        {
          information: "",
          from: "",
          to: "",
        },
        {
          information: "",
          from: "",
          to: "",
        },
      ],
information:"",
from:"",
to:""
}
 
...

 <input  type="text"   name="information"   onChange={(event)=>{this.setState({information:event.target.value})}   />
 <input  type="text"   name="from"          onChange={(event)=>{this.setState({from:event.target.value})}  />
 <input  type="text"   name="to"            onChange={(event)=>{this.setState({to:event.target.value})}   />

...

handleSubmit = (e) => {
    e.preventDefault()
const data={  information: this.state.information,
          from: this.state.form,
          to: this.state.to}

    this.setState({formData:[this.state.formData,data]})

    console.log(this.state.formData);
    }