0

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"?

0

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

2 Comments

This is more what I was looking for! Thanks alot!
@arkhz no worries, it was really good question, glad I could help!
1

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/

1 Comment

Thank you for the responses. This does solve my problem - but is it the best solution since it's a "uncontrolled component"? reactjs.org/docs/….

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.