Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React.js: setState overwriting, not merging

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!

like image 298
DanV Avatar asked Jul 22 '14 21:07

DanV


People also ask

Does React setState merge?

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 .

Why setState is not updating immediately?

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.

Does set state overwrite?

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 is setState () in React async instead of sync?

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.


1 Answers

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/

like image 120
Michelle Tilley Avatar answered Oct 18 '22 00:10

Michelle Tilley