javascript React JS:如何从 this.state.data 中正确删除一个项目,其中 data 是一个对象数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28975487/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 09:51:33  来源:igfitidea点击:

React JS: how to properly remove an item from this.state.data where data is an array of objects

javascriptreactjs

提问by Ted

I have a component that generates a table with rows of data (<tr>etc.) based on an array of data retrieved via an AJAX call. Everything works well for editing and adding the data, but I am unable to determine how to make a distinct copy of the array (with distinct copies of the contained objects - by val, not by ref) so that when I remove the specified row of data, the applicable rowis removed from the table.

我有一个组件,它<tr>根据通过 AJAX 调用检索的数据数组生成包含数据行(等)的表。一切都适用于编辑和添加数据,但我无法确定如何制作数组的不同副本(具有包含对象的不同副本 - 通过 val,而不是通过 ref),以便当我删除指定的行时数据,从表中删除适用的行

Currently, because the contained objects are by ref, even when I make a copy of the array, my table has the last row removed (even though the row index and data is all correctly referenced and deleted in my AJAX call).

目前,因为包含的对象是通过引用,即使我复制了数组,我的表也会删除最后一行(即使行索引和数据在我的 AJAX 调用中都被正确引用和删除)。

handleRowDelete: function(rowIdx) {
     // Correct row 
     var row = this.state.data[rowIdx];

     // This makes a new array, but the contained objects are still by ref
     var rows = this.state.data.slice();

     // This contains the proper row that will be deleted. If this array is set to data, the table is updated to reflect just the one row - as expected.
     var throwout = rows.splice(rowIdx, 1);
     console.log(throwout);

     // Whether I set via the React.addons: 
     var newState = React.addons.update(this.state, {
         data: { $set: rows }
     });
     this.setState(newState);

     // Or just set the state again via this.setState(...)
     //this.setState({data: rows, add: false});

     // It always just removes the last row in the component render
     // Even though the proper row gets deleted following in AJAX call
     $.ajax({
     ...
},
...    

I understand React can't make a proper diff so the render is not triggered, so can you show me how this should be handled?

我知道 React 无法进行适当的差异,因此不会触发渲染,所以您能告诉我应该如何处理吗?

UPDATE. Relevant loop:

更新。相关循环:

var Grid = React.createClass({
    propTypes: {
        data: React.PropTypes.array.isRequired,
        onCellChange: React.PropTypes.func.isRequired,
        onRowCommit: React.PropTypes.func.isRequired
    },
    render: function() {
        var rows = this.props.data.map(function(rowData, index) {
            return <Row key={index} data={rowData} onCellChange={this.props.onCellChange.bind(null, index)} onRowCommit={this.props.onRowCommit.bind(null, index)} onRowDelete={this.props.onRowDelete.bind(null, index)} />;
        }, this);

        return (
            <Table striped bordered hover responsive>
              <thead>
              <tr>
                <th className="col-sm-4">Order Subtotal (up to)</th>
                <th className="col-sm-2">Canada</th>
                <th className="col-sm-2">US</th>
                <th className="col-sm-2">International</th>
                <th className="col-sm-1"></th>
              </tr>
              </thead>
              <tbody>
                    {rows}
              </tbody>
            </Table>  
        );
    }
});

回答by WiredPrairie

You'll need to make sure that the keyvalue remains a constant for the lifetime of the object instance. As you have it coded, the keyvalue is based on the indexinto the Array. If you remove one element from the Array, the indexes are updated, and so would be the keys. And, as a result, an object's keywould change, and React will appear to not properly apply the new array changes (even when the underlying array has changed).

您需要确保该key值在对象实例的生命周期内保持不变。当您对其进行编码时,该key值基于index进入Array. 如果从 中删除一个元素Array,则索引会更新,键也会更新。并且,结果,一个对象的key会发生变化,并且 React 似乎无法正确应用新的数组更改(即使底层数组已更改)。

You'll need to either use a unique value from each object instance as the keyor create one artificially (just assign a unique number to each object).

您需要使用来自每个对象实例的唯一值作为key或人工创建一个(只需为每个对象分配一个唯一编号)。

回答by Jeff Gu Kang

Use unique key is in Data Objectsas below.

使用唯一键在数据对象中,如下所示。

data = [
  {
    id: 0,
    contents: 'data 0',
  },
  {
    id: 3,
    contents: 'data 3',
  },
  {
    id: 4,
    contents: 'data 4',
  },
];


var rows = this.props.data.map(function(rowData, index) {
            return <Row key={rowData.id} data={rowData} onRowDelete={this.props.onRowDelete.bind(null, index)} />;
          }, this);

React do not re-render the component has the same key as one before.

React 不会重新渲染具有与之前相同的键的组件。