admin管理员组文章数量:1208153
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>
);
}
});
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>
);
}
});
Share
Improve this question
edited Mar 11, 2015 at 2:17
Ted
asked Mar 10, 2015 at 22:45
TedTed
7,25110 gold badges52 silver badges76 bronze badges
6
|
Show 1 more comment
2 Answers
Reset to default 16You'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.
本文标签:
版权声明:本文标题:javascript - React JS: how to properly remove an item from this.state.data where data is an array of objects - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738762694a2111054.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
key
attribute to eachtr
so that React knows what's changed properly? facebook.github.io/react/docs/… – WiredPrairie Commented Mar 11, 2015 at 0:47key
isn't unique to the row. You're just using the index..., which means that if you remove something, the index has changed. – WiredPrairie Commented Mar 11, 2015 at 3:07