I'm quite new to React.JS and I am in the process of experimenting by building a masonry-style layout.
I render each element to the DOM, then I need to loop over each item and apply x and y positions based on the preceding elements.
The initial model looks like this:
[ { "title": "The Forrest", "description": "some cool text", "imgSmallSrc": "/img/img4-small.jpg", "imgAlt": "Placeholder image", "tags": [ "Design", "Mobile", "Responsive" ], "date": 1367154709885, "podStyle": { "width": 253 } } ]
(I've only shown one item to keep things short).
Once I complete the loop and have my x and y data I want to apply this to the podStyle
object. I call setState()
with the following data:
[ { "podStyle": { "x": 0, "y": 0, "height": 146, "width": 253 } } ]
This seems to remove all current data from the model and leave me with just the podStyle
data. Am I misunderstanding how this merge works?
Thanks in advance for any help!
When you call setState() , React merges the object you provide into the current state. The merging is shallow, so this.setState({comments}) leaves this.state.posts intact, but completely replaces this.state.comments .
setState , and React. useState create queues for React core to update the state object of a React component. So the process to update React state is asynchronous for performance reasons. That's why changes don't feel immediate.
When you update state by passing an object inside setState(), the state is updated by shallow merging. Shallow merging is a concept in javascript,using which if two objects are merged, the properties with same keys are overwritten by value of the same keys of second object.
Why setState() is async? ReactJs sets its state asynchronously because it can result in an expensive operation. Making it synchronous might leave the browser unresponsive. Asynchronous setState calls are batched to provide a better user experience and performance.
If your state is an object:
getInitialState: function() { return { x: 0, y: 0 }; }
you can use setState
to set individual keys on that object:
this.setState({ x: 1 }); // y still == 0
React does no intelligent merging of your state; for example, this does not work:
getInitialState: function() { return { point: { x: 0, y: 0 }, radius: 10 }; } this.setState({point: {x: 1}}); // state is now == {point: {x: 1}, radius: 10} (point.y is gone)
[Edit]
As mentioned by @ssorallen, you can use the immutability helpers to get the effect you're after:
var newState = React.addons.update(this.state, { point: { x: {$set: 10} } }); this.setState(newState);
See this JSFiddle for an example: http://jsfiddle.net/BinaryMuse/HW6w5/
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