I am trying to create a table component in React where both the columns and rows are dynamic and change over time. However, when the data changes, React throws an unexpected DOM mutation invariant violation.
Here is a fiddle demonstrating the issue http://ift.tt/1yCKZmu. As you can see, the data changes after the initial render and React can no longer track the state of the DOM.
Code is here:
var Table = React.createClass({
getDefaultProps: function() {
return {
data: [
{
colA: { value: 'foo' },
},
],
};
},
render: function() {
return (
<table>
<thead>
<tr> {
Object.keys(this.props.data[0]).map(function(key) {
return (<th>{ key }</th>);
}.bind(this))
} </tr>
</thead>
<tbody> {
this.props.data.map(function(item) {
return (<tr> { Object.keys(item).map(function(key) {
return (
<td>{ item[key] }</td>
);
}.bind(this)) } </tr>);
}.bind(this))
} </tbody>
</table>
);
}
});
var Main = React.createClass({
componentWillMount: function() {
setTimeout(function() {
var data = [
{
colA: {
value: 'foobar',
},
},
];
this.setState({
data: data,
});
}.bind(this), 3000);
},
getInitialState: function() {
var data = [
{
colA: {
value: 'foo',
},
colB: {
value: 'bar',
}
},
{
colA: {
value: 'foo',
},
colB: {
value: 'bar',
}
}
];
return {
data: data,
};
},
render: function() {
return (<Table data={ this.state.data } />);
},
});
React.render(<Main />, document.body);
console.log(React.renderToString(<Table/>));
I've tried all manner of adding key attributes to track various elements and nothing seems to solve this problem.
Rendering the table component with renderToString shows that React is inserting a bunch of elements at various levels of the table. Is this the possible cause? See the DOM being rendered here:
<table data-reactid=".1" data-react-checksum="1098817301">
<thead data-reactid=".1.0">
<tr data-reactid=".1.0.0">
<span data-reactid=".1.0.0.0"> </span>
<th data-reactid=".1.0.0.1:0">colA</th>
<span data-reactid=".1.0.0.2"> </span>
</tr>
</thead>
<tbody data-reactid=".1.1">
<span data-reactid=".1.1.0"> </span>
<tr data-reactid=".1.1.1:0">
<span data-reactid=".1.1.1:0.0"> </span>
<td data-reactid=".1.1.1:0.1:0"><span data-reactid=".1.1.1:0.1:0.$value:0">foo</span></td>
<span data-reactid=".1.1.1:0.2"> </span>
</tr>
<span data-reactid=".1.1.2"> </span>
</tbody>
</table>
Aucun commentaire:
Enregistrer un commentaire