mweststrate
Immer: Create the next immutable data tree by modifying the current one
Looking like, and being like are two different things :) Mobx reminds people (rightfully) of Meteor, Knockout, Angular etc, but when working with it you will see it is quite a different best. Just like Redux will remind people of flux, but that doesn't mean people shouldn't try Redux because e.g. Facebook Flux didn't work out.
The fundamental principles behind MobX
For example in proppy.io, as described here: https://blog.wearewizards.io/a-mobx-introduction-and-case-st...
In practice it turns out to work very well for large apps and many people use it that way (https://twitter.com/_ericelliott/status/766812933804269568)
More in depth: https://egghead.io/courses/manage-complex-state-in-react-app...
How to decouple state and UI (a.k.a. you don’t need componentWillMount)
Serializr: serialize and deserialize JavaScript object graphs to JSON with ease
3 Reasons why I stopped using React.setState
Why we chose MobX over Redux for spectacle editor
For the last question: yes exactly. Note that the observables can (should) usually be updated from a 'nice' place, for example from controller or class methods, as directly manipulating data inside event handlers (as done in the tutorial for brevity) will quickly result in your code becoming a mess. But besides that state should be updated in the most straight forward way possible :). So MobX is unopiniated from a technical perspective, but you should have some opinion about it so that code is regularly structured and easy to grasp by others.
Note that MobX itself also uses reference equality checking (it applies PureRenderMixin), see this issue for an explanation why that is possible: https://github.com/mobxjs/mobx/issues/101#issuecomment-18987...
MobX is still unidirectional data flow: `events / actions => state => view` (although you could create React components that are bidirectional a recommend against that). But if you mean with unidirectional data flow that there is no action dispatcher; that is up to the developer. Having an action dispatcher might still be nice for your app. Or over engineering. MobX is unopiniated about these things.
I'm not sure whether this answers your question completely, so just let me know if that is the case :)
Make state management simple again: Intro to MobX
Just scan through my blog https://www.mendix.com/tech-blog/making-react-reactive-pursu... to see how naively fully re-rendering your application upon each change makes your application an order of magnitude(!) slower.
Data size isn't usually an issue for MobX. The reason for that is that it will automatically suspend all derivations which are not actively in use somewhere (in other words, not visible currently in the screen). We have full blown visual editors that have hunderd thousands observables in memory. Nonetheless they are fast enough to perform drag and drop actions using observables, where not only the dragged item is being moved, but also all the connectors connected to it, as they observe the item being dragged.
This approach enables our partners to write plugins that are not only simple to write, because they can just work with 'plain' javascript classes and arrays (and don't need to learn the whole, for example, redux architecture), but which are also really easy to integrate in our visual tools. Our UI stays always efficiently in sync with whatever mutations plugins make. In an architecture with explicit subscriptions, events or selectors this would be a lot harder to achieve.
That statement refers to the fact that you loose (automatic) referential integrity when you start using Immutable data.
Take the following scenario: you have an app with Users and Tasks. Tasks can be assigned to users. When you express this using immutable data you have two problems. The first one is linking tasks to users. If you would link Task1 to Person1 and after that change the name of Person1, you would get a new person, Person1v2. However Task1 would still refer to the old, unmodified Person1, so then you have suddenly two versions of the same person in memory. A fresh and a stale one. In other words, you lost referential integrity.
Now the usual way to fix is, is to not use real references, but to normalize data and store only a key to the person. The effect of this is that you have to always lookup the person related to Task1 again from the state tree. If you have a reference (variable) to that person somewhere, make sure it is short-lived because you won't know if you are still referring to the correct one.
The second problem is that when you have correctly normalized your data and always do fresh lookups, you will still not know _when_ to make these lookups. If you have a TaskView that renders the name of the related Person, and the related person changes, the TaskView will not detect this automatically. The related person is not even a prop of the TaskView component so pushing a new state tree through your app won't repaint the TaskView if you are using PureRenderMixin (which is usually the purpose of using immutable state trees in the first place). For that issue there is a solution as well; you can introduce selectors (or lenses) that query the state tree to detect if the relevant person is changed. So now we already have three new concepts (no refs, normalization, lookups, selectors) to solve a problem that mutable data doesn't have in the first place.
By using mutable data and observing it using MobX these problems are solved (imho) more elegantly: references are never stale because if you would modify Person1, Task1 would still refer to the 'latest' person1, because it is still the same object. Secondly, because it is the same object, fine grained object observers can be established automatically for you, making sure the TaskView gets updated as soon as something relevant changes. This means that you have less concepts to learn and maintain (no copy-on-write, no need to assign a unique key to everything, no data normalization, no lookups, no selectors to make sure your views are always in sync with the state). That saves a significant amount of boring yet error prone work when your application's state model becomes more complex than the average Todo app.
So that is the long story behind that short comment. I hope it clarifies the statement!
The best way to build large scale apps with Flux
I wrote a short blog post about the issue: https://medium.com/p/object-observe-is-dead-long-live-mobser.... Mobservable currently relies on property getters / setters, both for arrays and objects. Probably until proxies will be generally available.