-1

I render the values that I have inside an object and an input next to each of them with that object index item as value. When I try to use the onChange prop, I cannot modify neither the rendered value nor the input value. How can I do this changing the state of the element in the array?

I want the Toto value to be modified as I change the input value

I want the Toto value to be modified as I change the input value

My object players looks like this:

[
  {
  "name": "Toto";
  },
  {
   "name": "Lolz",
  }
]

Here, I try to render my table:

modifyItem = (event, index) => {
   this.state.players[index].name = event.target.value
   //my problem is clearly here
}

render() {
    const playersList = [...new Array(this.state.players.length)].map((it, index) => {
    return (
    <tr key={index}>
      <td>{this.state.players[index].name}</td>
        <input type="text" value={this.state.players[index].name} onChange={this.modifyItem}/>
      </td>
    </tr>
    )
    })

    return () {
      <div>
         {playersList}
      </div>
    }

What I want to do is:

In each element of the table AND input ( for example the first one Toto), I want to modify this value in the input and consecutively in the table. I can't seem to find the correct answer.

6
  • The array is not empty because the value is rendered (notice the picture link). I'm not posting the entire code Commented Mar 29, 2019 at 14:12
  • I missed the [...] part. But that's a hugely convoluted way to just do this.state.players.map(): pastebin.com/f1uMbtaK Commented Mar 29, 2019 at 14:15
  • It's not clear what you're asking. You've said you want to 'change" something, but you've shown us a render function. You don't change things in render. Please update your question with a minimal reproducible example demonstrating the problem, ideally a runnable one using Stack Snippets (the [<>] toolbar button). Stack Snippets support React, including JSX; here's how to do one. Commented Mar 29, 2019 at 14:16
  • Alright thanks for the tip. Do you know how would I be able to change the tables value (the element of my state object players[index].name) that is being modified in my input? Commented Mar 29, 2019 at 14:16
  • Please post the whole code if you want help. Also, I suggest learning and using Formik when doing forms in React. Specifically, its FieldArray (jaredpalmer.com/formik/docs/api/fieldarray) component in your case. It'll save you a lot of hassle compared to vanilla React in the end. Commented Mar 29, 2019 at 14:17

1 Answer 1

1

I've created a codesandbox example for you here:

https://codesandbox.io/s/vnkoxop6z3

You need to store your values in state, and when you modify each item you need to know what the new value is via the onChange callback, and the index of that current value.

From here you can duplicate the array by spreading it into a new one, access that particular index item on the new array, and update the name with the new value.

Once you have done this. setState with the new array.

class Component extends React.Component {
  constructor() {
    super();
    this.state = {
      values: [
        {
          name: "Toto"
        },
        {
          name: "Lolz"
        }
      ]
    };
  }

  modifyItem(e, index) {
    const newValue = e.target.value;
    const values = [...this.state.values];
    values[index].name = newValue;

    this.setState({
      values
    });
  }

  render() {
    return this.state.values.map((value, index) => {
      return (
        <Fragment>
          <label>{value.name}</label>
          <input
            type="text"
            value={value.name}
            onChange={e => this.modifyItem(e, index)}
          />
        </Fragment>
      );
    });
  }
}

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

2 Comments

Perfect, thanks! This is exactly what I was looking for. What exactly does the [...this.state.values] mean?
No problem. It expands out iterable items. You can read more about it here on MDN developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… I used it in this instance to create a duplicate array before modifying it. Its a preferred method instead of modying existing data you should create a duplicate of it first. Here is an answer on immutability stackoverflow.com/questions/12207757/…

Your Answer

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