1

This maybe a silly question, so I apologize in advance.

I have a small array where I iterate it with this.state.data.map() and pass the data into inputs. I would like to edit the data in each input and save the new data. Since it's an array, how can I save this new data into the array? Which is the best/smartest practice for this?

A live example here

Here is an example below:

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      data: ["Saab", "Volvo", "BMW"],
      editMode: false
    };
  }

  handleInput = e => {
    let value = e.target.value;
    let name = e.target.name;
    console.log(name);
    console.log(value);

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

  handleFormSubmit = e => {
    e.preventDefault();

    const { data } = this.state;
    console.log(data);
  };

  render() {
    return (
      <div className="App">
        <div>
          {!this.state.editMode ? (
            <button onClick={() => this.setState({ editMode: true })}>
              edit
            </button>
          ) : (
            <div>
              <button onClick={() => this.setState({ editMode: false })}>
                cancel
              </button>
              <button onClick={this.handleFormSubmit}>submit</button>
            </div>
          )}
        </div>

        <React.Fragment>
          {this.state.data.map((rule, index) =>
            this.state.editMode ? (
              <form onSubmit={this.handleFormSubmit}>
                <input
                  onChange={this.handleInput}
                  type="text"
                  placeholder="Cars"
                  name={rule}
                  defaultValue={rule}
                  key={index}
                />
              </form>
            ) : (
              <p key={rule}> - {rule} </p>
            )
          )}
        </React.Fragment>
      </div>
    );
  }
}

Thank you! :)

1
  • Is values are unique in state.data? Else every identical value will be replaced with new one. Commented Jan 27, 2019 at 13:58

3 Answers 3

4

One solution is to pass the index of the currently changed item to the event handler to ensure that you are modifying the correct item on the list.

To do this, change your handleInput to accept both the event object and index of the currently changed item.

handleInput = (e, index) => {
  const { data = [] } = this.state;
  let value = e.target.value;
  data[index] = value;
  this.setState({ data: data });
};

So you have to changed your input onChange handler to this.

onChange={(event) => this.handleInput(event, index)}

See working example

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

3 Comments

Your working example is not working :P. @Ana Liza Pandac
@RChohen I forgot to save it.:D
ahaha it's okay :)
0

First problem is that, your data is an array while in handleInput you are assigning it to the object.

Second, coming to your problem, I am assuming order of the array is also important. You should set new value on onchange at the same index the prev. value was.

The following code should work:

handleInput = (value, index) => {
  this.setState(prevState => {
    const newData = prevState.data;
    newData[index] = value;
    return {
        data: newData
    };
  });
};

And input element be like:

<input
  onChange={(e) => {this.handleInput(e.target.value, index)}
  type="text"
  placeholder="Cars"
  value={rule}
  key={index}
/>

Comments

0

Do this

handleInput = e => {
  let value = e.target.value;
  let name = [e.target.name];
  console.log(name);
  console.log(value);

   let { data } = this.state;
   data[name]  = value;

    this.setState({data: data});
 };

Comments

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.