1

我正在动态地将表行添加到表中。下面是它在 UI 中的外观:

示例截图

这是我用来创建新行的逻辑:

我有一个状态变量this.state = ({rows: []})

在“插入”按钮上单击我正在做的事情:

addNewRow = () => {
        this.setState({rows: this.state.rows.concat([{}])});
    }

在我的render()我有以下代码:

const rows = this.state.rows.map((item, id) => {
            return(
                <tr key={id}>
                    <td>Something</td>
                    <td>Something</td>
                    <td>Something</td>
                    <td>Something</td>
                    <td><Button onClick={(event) => this.removeRow(event, id)}>Delete</Button></td>
                </tr>
            );
        });

而且,显然我的决赛桌代码如下所示:

<Table borderless>
    <tbody>
       {rows}
    </tbody>
<tfoot>
    <tr>
       <td>
        <Button onClick={() => {this.addNewRow()}} size="sm" className="float-left">insert</Button>
       </td>
    </tr>
</tfoot>
</Table>

这是我的removeRow功能:

removeRow = (event, id) => {
        event.preventDefault();
        var index = this.state.rows.indexOf(id);
        this.state.rows.splice(index, 1);
        this.setState({rows: this.state.rows});
    }

整个代码有效。我已经更改了变量名称并从中删除了不需要的代码,但这是为了了解我是如何设计它的。

我的问题是当我点击“删除”按钮时,它总是删除行中的最后一个项目,而不是我点击的项目行。如何解决这个问题?

我用谷歌搜索了一下,发现很少有例子,老实说,我觉得它们很复杂,所以我决定走自己的路。

请告知需要做些什么来解决这个问题。

4

3 回答 3

1

那是因为您使用数组索引作为<tr>元素的键。

React 使用key来标识要从现有 DOM 树中插入或删除的内容。

请使用任何其他唯一标识符,例如,Date.now()作为密钥,并将此密钥保存为rows状态的一部分。

addNewRow = () => {
  const { rows } = this.state
  this.setState({
    rows: [
      ...rows,
      {
        id: Date.now(),
      },
    ],
  })
}

render() {
   const rows = this.state.rows.map((item, index) => (
     <tr key={item.id}>
     </tr>
   ))
}
于 2018-06-29T06:52:01.117 回答
1

永远不要在 React 中直接改变状态:

你需要这样做:

removeRow=(event,id)=>{  
  var array = [...this.state.rows]; // make a new copy of array instead of mutating the same array directly. 
  var index = array.findIndex(x => x.id===id); //find the index of item which matches the id passed to the function
  array.splice(index, 1);
  this.setState({people: array});
  }
于 2018-06-29T06:37:56.747 回答
0

那是因为你用.map()错了。

你需要item像这样通过:

<td><Button onClick={(event) => this.removeRow(event, item)}>Delete</Button></td>

您将数组的索引传递为id. 因为,array.map运算符的第二个参数是该元素在数组中的索引。

改为这样做:

removeRow = (event,item) => {  
  var array = [...this.state.rows]; // make a new copy of array instead of mutating the same array directly. 
  var index = array.indexOf(item)
  array.splice(index, 1);
  this.setState({people: array});
  }
于 2018-06-29T06:52:13.373 回答