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 row is removed from the table. 
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).
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?
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>  
        );
    }
});
                To remove an element from an array of objects in React: Use the filter() method to iterate over the array. On each iteration check if a certain condition is met. The filter method returns an array containing only the elements that satisfy the condition.
React has a top-level API called unmountComponentAtNode() that removes a component from a specific container. The function unmountComponentAtNode() takes an argument as a container from which the specific component should be removed.
To filter an array of objects in React: Call the filter() method on the array. On each iteration, check if a certain condition is met. The Array. filter methods returns an array with all elements that satisfy the condition.
You'll need to make sure that the key value remains a constant for the lifetime of the object instance. As you have it coded, the key value is based on the index into 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 key would change, and React will appear to not properly apply the new array changes (even when the underlying array has changed). 
You'll need to either use a unique value from each object instance as the key or create one artificially (just assign a unique number to each object).
Use unique key is in Data Objects as 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With