arkhz
arkhz

Reputation: 291

Change value on dynamic input fields in reactjs

I am trying to change the input value on dynamically added input fields.

Each input field value is set to a state value which is made of an array.

Seems like there should be a simple solution for this.. But I can't just figure it out.

JSfiddle: https://jsfiddle.net/o51Lkvm6/1/

handleInputChange = (e) => {
    this.setState({
        [e.target.name]: e.target.value
    });
}

    render()  {
        return (
            <div>
                { this.state.data.map((d, index) =>
                    <input name={d.Name} type="text" className="form-control" 
                  value={d.Name} onChange={this.handleInputChange} />
                 )}
            </div>
        );
    }

Update: Is it possible to solve this without having to use defaultvalue? Since React does not recommend "Uncontrolled Components"?

Upvotes: 0

Views: 3646

Answers (2)

maaajo
maaajo

Reputation: 1035

First of all there are couple issues with your code:

  • You forgot to bind your handler method or use arrow function to preserve this context of a class. To fix that you can either put this in Test constructor:
this.handleInputChange = this.handleInputChange.bind(this)

or modify your existing function to:

  handleInputChange = e => {};
  • Input value should actually use the value which corresponds to current item from state, like that:
value={this.state.data[index]["Name"]}
  • Later to access proper item in your stateData you have to somehow store that index in the input. I did this by assigning it to data-index attribute. Also you forgot to include key prop:
 <input
   key={d.ID}
   data-index={index}
   name={d.Name}
   type="text"
   className="form-control"
   value={this.state.data[index]["Name"]}
   onChange={this.handleInputChange}
  />
  • In your actual handleInputChange you were not targeting the correct thing. You need to first get the appropriate item from the array and then modify the name. I did it by copying the actual state and later assigning it:
  handleInputChange = e => {
    const stateDataCopy = this.state.data.slice();
    const objectCopy = Object.assign({}, stateDataCopy[e.target.dataset.index]);
    objectCopy["Name"] = e.target.value;
    stateDataCopy[e.target.dataset.index] = objectCopy;
    this.setState({ data: stateDataCopy });
  };
  • Here you can find working example:

Edit cranky-maxwell-ob3tl

Upvotes: 1

Red Baron
Red Baron

Reputation: 7682

ok I fixed it for you

do these 2 things

handleInputChange(e){ make this an arrow function so it has the concept of this like so: handleInputChange = (e) => {

and use defaultValue instead of value in the input

updated fiddle for you: https://jsfiddle.net/a17gywvp/1/

Upvotes: 1

Related Questions