Reputation: 15045
/**
* @jsx React.DOM
*/
var Dummy = React.createClass({
mixins: [React.addons.LinkedStateMixin],
getInitialState: function() {
return [42, 54];
},
render: function() {
return <div>
{this.state.map(this.renderItem)}
<pre>{JSON.stringify(this.state, null, 2)}</pre>
</div>
},
renderItem: function(item, i) {
return <div>
<input type="number" valueLink={this.linkState(i)}/>
</div>
}
});
React.renderComponent(
<Dummy/>,
document.body
);
When I’m changing numbers in the input fields React throws:
Uncaught Error: Invariant Violation: Critical assumptions about the merge functions have been violated. This is the fault of the merge functions themselves, not necessarily the callers.
Is it a bug in React? Is merging arrays not working?
Upvotes: 3
Views: 1850
Reputation: 92210
Your state is an array.
I didn't see anything in the React doc mentioning the LinkedStateMixin mixin could link an input to an array index.
What happens is probably:
[42, 54]
As setState()
doesn't override an existing state but merges the new state into the existing state (because you only update one input at a time), then React is trying to merge a JSON object into a JS array. Which is weird :)
Actually your initial values are displayed correctly because both array[index]
and object[key]
works the same.
I don't think React support arrays well for now but it's worth opening a pull request maybe.
For now you can try to use objects like this:
var Dummy = React.createClass({
mixins: [React.addons.LinkedStateMixin],
getInitialState: function() {
return {0: 42, 1: 54};
},
render: function() {
return <div>
{Object.keys(this.state).map(this.renderItem)}
<pre>{JSON.stringify(this.state, null, 2)}</pre>
</div>
},
renderItem: function(key) {
return <div>
<input type="number" valueLink={this.linkState(key)}/>
</div>
}
});
By the way you may try to create your own LinkedStateMixin to link to an array index, has you have done there:
React.js 2-way bindings: two-levels deep path in valueLink
I just wonder if it is possible in React to have state = [42, 54]
and then setState([undefined, 55])
to finally have state = [42, 55]
, please tell us :)
Upvotes: 3