входное значение реакции не синхронизируется с домом - PullRequest
0 голосов
/ 20 сентября 2018

У меня есть цикл для рендеринга группы входных данных, он динамический, пользователь может добавлять строки и удалять строки, но введенное значение не синхронизируется при уничтожении элемента.

, как вы можете видеть в демонстрацииЯ удалил «2», но «3» был удален, а 2 все еще там.

enter image description here

Код: https://codesandbox.io/s/4x0x17zykx

1 Ответ

0 голосов
/ 20 сентября 2018

Это из-за вашего метода deleteRow.

deleteRow = () => this.setState({ rowCount: this.state.rowCount - 1 });

Этот метод просто меняет значение state.rowCount, и когда вызывается метод рендеринга, вы отображаете строки с 0 до rowCount.

return <div>{times(rowCount, this.renderRow)}</div>;

Таким образом, вы фактически удаляете последнюю строку, а не строку, по которой щелкнули.

РЕДАКТИРОВАТЬ: Вы можете получить ожидаемое поведение с некоторыми изменениями (Созданиемассив строк внутри состояния, обновляющий методы deleteRow и addRow для правильной работы и добавление события onChange на входы, чтобы показать, что удаленная строка является ожидаемой)

import React from "react";
import ReactDOM from "react-dom";
import times from "lodash.times";

export class MultipleInput extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      rows: [{type: "", value: ""}],
    };
  }


  addRow = () => {
    this.setState((prevState) => ({
      rows: prevState.rows.concat({type: "", value: ""})
    }));
  };

  deleteRow = (i) => {
    this.setState((prevState) => ({
      rows: prevState.rows.filter((_, index) => index !== i)
    }));
  };

  onChange = (e, i) => {
    let rows = this.state.rows.slice();
    rows[i].value = e.target.value;
    this.setState(
      rows: rows,
    );
  };

  renderRow = (i) => {
    return (
      <div>
        <input index={i} type={this.state.rows[i].type} value={this.state.rows[i].value} onChange={(e) => this.onChange(e, i)}/>
        {i === 0 && <button onClick={() => this.addRow()}>add row</button>}
        {i > 0 && <button onClick={() => this.deleteRow(i)}>x</button>}
      </div>
    );
  };

  render() {
    return <div>{times(this.state.rows.length, this.renderRow)}</div>;
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<MultipleInput />, rootElement);

Этот код, конечно, не самый чистыйили более эффективный, но он работает и (я надеюсь) не реагирует на анти-паттерн.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...