Как мне обработать onChange объектов внутри массива (React State)? - PullRequest
0 голосов
/ 08 февраля 2020

сообщество,

Я пытаюсь создать таблицу, в которой ее строки отображаются на основе массива объектов:

this.state = {
  tableContent: [
    { 
      id: this.state.tableContent.length,
      firstname:"",
      lastname:""
    },
    ...
  ]

В каждой строке отображается один объект. (2 столбца в данном случае, n строк) Каждая ячейка также является полем ввода, поэтому пользователи могут манипулировать таблицей:

<tbody>
  {this.state.tableContent.map((row) => {
    return(
      <tr key={row.id}>
        <td><input value={row.firstname} onChange={this.handleFirstNameChange}> </input></td>
        ...
      </tr>
    )
  })}
</tbody>

Я хочу, чтобы каждая ячейка / поле ввода отображала изменение, когда пользователь изменяет входное значение и как таковое состояние. Поскольку я предварительно заполняю поле ввода с помощью value={row.firstname}, мне нужно определить функцию-обработчик onChange, которая изменяет состояние / значение свойства firstname целевого объекта.

Так как же мой onChange функция обработчика похожа? Я пытался использовать спреды, но пока безрезультатно ...

Некоторые мысли: использование стандартной процедуры не работает, потому что у меня есть вложенное состояние (массив объектов):

handleChange = (event) => { this.setState({ firstname: event.target.value }) } 

Попытка использовать оператор распространения также приводит к некоторому странному беспорядку: (этот код здесь несколько неправильный: может быть, вы можете это исправить?)

handleFirstNameChange = (event) => {
    const {tableContent} = {...this.state};
    const currentState = tableContent;
    const { firstname, value } = event.target;
    currentState[0] = value;
    this.setState({ tableContent: currentState});
  }

Я ценю любую помощь!

edit: код ниже, кажется, почти работает. (спасибо @Nikhil) Однако теперь, когда пользователь вводит в поле ввода, каждая введенная им буква заменяет существующую букву / значение 'row.firstname'. Кроме того, состояние не обновляет sh автоматически, поэтому будет отображаться / сохраняться только последняя напечатанная буква. Что мне нужно, чтобы поле ввода имело такую ​​же функциональность, как любое случайное поле ввода. event.persist (); кажется, что необходимо сохранить значение события.

handleFirstNameChange = (id, event) => {
    event.persist(); 
    this.setState(prevState => {
      tableContent : prevState.tableContent.forEach((row) => {
        if(row.id === id) { row.firstname = event.target.value}
      })
    })
  }

ввод выглядит следующим образом:

onChange={(event) => this.handleWNRChange(row.id,event)}

Ответы [ 2 ]

1 голос
/ 08 февраля 2020

Я думаю, что-то вроде этого будет работать.

const handleFirstNameChange = (id, event) => {
    event.preventDefault();
    const {tableContext} = this.state;

    const myRowIndex = tableContext.findIndex((row) => row.id === id);
    tableContext[myRowIndex].firstname = event.target.value;

    this.setState({ tableContext });
}

Это должно быть все, что вам нужно. Просто назначьте этот метод элементу onChange элемента input. Вот так:

onChange={(event) => this.handleFirstNameChange(row.id, event)}
0 голосов
/ 08 февраля 2020

Может быть, это поможет

{this.state.tableContent.map((row, index) => {
    return(
      <tr key={row.firstname}>
        <td><input value={row.firstname}
             onChange={(event)=>this.handleFirstNameChange(event, index)> </input></td>
      </tr>
    )
  })
}

handleFirstNameChange(event, index){
  this.setState((prevState => {
      tableContent : prevState.tableContent.forEach((row,i)=>{
        if(index === i) row.firstname = event.target.value
      })
  })
}
...