4 ms·
Since assignment of an object is by reference, if you say: var stateB = stateA, then both stateA and stateB now point to the same JS object. If you change state
by idibidiart 11y ago
Since assignment of an object is by reference, if you say: var stateB = stateA, then both stateA and stateB now point to the same JS object. If you change stateB then stateA will be changed too since they both point to the same object
So you would have to do: var stateB = JSON.parse(JSON.stringify(stateA))
to get a copy and then you can change stateB and it will not be equal to stateA.
The problem is without use of actual "persistent data structures" (not "immutables" based on Object.freeze etc) the copy/clone operation is expensive. With persistent data structures as in ImmutableJS you get faster (O(1)?) copy. Therefore, building your state store on ImmutableJS and doing an explicit comparison (if you're using React) with shouldComponentUpdate by comparing 'prevState != curState' is the only thing you need, and I had seen benchmarks that show 35% increase in performance over not using ImmutableJS.
Update:
in response to the question about having a list of items and React invoking shouldComponentUpdate, that should not be the case if React stops comparing when the parent aka the list itself says that update should not happen. Does React in that case descend down the tree to compare the state of the list items? I suppose it would but there must be a way adound it. I heard about batchUpdate add-on in this context. Researching now!
- amelius 11y agoBut let's say the UI consists of a list of N text elements. That list is encoded as an immutable vector. When one of the elements changes, react will run through the complete list and call shouldComponentUpdate for each item (!) In contrast, with a fast "diff" operation, we could simply determine which of the elements in the state have changed, and this would be fast.
- deleted 11y ago[deleted]
- epmatsw 11y agoHow would you implement a fast diff that didn't involve looking at each text value anyways? Would there be a separate store in the structure that tracks changes, or something along those lines?
- amelius 11y agoYou can do this by skipping over shared sub structures, while comparing, for example.
- epmatsw 11y agoI don't see how that is related to immutability. Immutability gives you the ability to verify that it's unchanged in O(1), but it doesn't change your ability to do optimizations like that...
- amelius 11y agoWell, immutable data-structures use "structural sharing", internally. Search for it. For example, this image, [1], shows two data-structures (the green nodes), that internally share many nodes. Now, comparing those two structures can be done efficiently, because the shared parts don't need comparing. [1] http://eclipsesource.com/blogs/wp-content/uploads/2009/12/clojure-trees.png http://eclipsesource.com/blogs/wp-content/uploads/2009/12/cl... (a random image I found on the internet that illustrates my point)
- epmatsw 11y agoWouldn't that be an argument for using an immutability library then? If you can implement a shallow equality that takes shared structures into account, what about non-immutable structures makes them a more efficient option for such a thing?
- idibidiart 11y agoTake a look at this: https://github.com/mquan/cortex https://github.com/mquan/cortex "Cortex is simply a store that works for updates at any level. It achieves this by utilizing cursors, which lets each nested node keep track of its path as accessed from the root. When an update occurs, the affected node emits an update event whose payload contains the path of the node as well as instructions on how to update the data at the root. Cortex's internal PubSub picks up the event and routes it to the affected root node. From there, every affected node is rewrapped and updated to maintain immutability while leaving all unaffected nodes untouched. This allows for extremely simple and efficient"