Hacker News new | past | comments | ask | show | jobs | submit login
MobX – Simple, scalable state management for React (mobxjs.github.io)
62 points by gedy on Aug 27, 2016 | hide | past | favorite | 26 comments

I wrote a very large app in Knockout back in the day, and ran into significant problems with Knockout's computeds and the two way data binding.

It was great to start with, but as the app got larger and more involved, performance started to suffer (from all the different observables and computed triggering and retrigger on a change), memory leaks started to creep in, and eventually I started noticing weird glitches where bits of the UI wouldn't by entirely in-sync. Worse, there was very little I could do to fix it, because the bug was deep in Knockout's "magic". My models had correct data, but sometimes my UI would not.

The lesson I picked up from that was that that sort of magic was bad news, and for my next major project I used React, and when I needed state management I eventually ended up with Redux. I won't lie: There's been some pain points, there's a lot less hand holding, more boilerplate, etc. But performance has been amazing and there's been no issues where something other than my poor coding has caused a bug. Redux code is very, very deterministic: You state looks like X, then you have an event Y, and now your state looks like Z. That state is fed into your component hierarchy, and DOM elements come out the end. If you don't like the result, you can quickly narrow it down to being a bug in your render methods, your reducers, or your actions. No magic.

MobX...looks great. But it looks great in the specific ways that Knockout burned me in the past. Does anyone have any input on that? If I go all-in on Redux and write a very large and interconnected app, I have confidence that:

1) Writing all the reducers and selectors will be pretty big pain

2) Once I do it it'll work just as smoothly as a hello world app will.

If I go all in on MobX, it looks like it'll be easier to write, but...how's it going to run? Saying "inspired by Knockout" gives me distinctly mixed feelings, seeing as how I started using React to get away from Knockout. :)

I've built the same app in both Redux and MobX.

Things I noted:

1) Agree with your #1. It's a pain of boilerplate.

2) Agree, Redux is very easy to reason about and debug.

2) MobX was definitely much faster to develop.

3) MobX performance was better out the box. I may have done something wrong, however I have noted this with the mortgage example.

4) MobX has its own pain points when trying to build more advanced (tree) data structures. Creating a nested observable object requires creating map objects at every step of the tree. This makes using libraries such as lodash difficult.

5) I prefer the redux dev tool

6) Redux containers works well at the top level, however implementing a reusable container requires more boilerplate code. Since there is no consensus library or approach here - I implement my own solution with caution.

7) It is possible to use both redux and mobx on the same app, but you need to know what you're doing. Additionally you seem to lose some of the benefits of redux when you do this.

8) You can communicate between stores, but I feel this is a bad approach and will lead to messy code.

In the end I chose to proceed with Redux, however I think MobX implemented with proxy objects would be amazing.

I look forward to a framework that sits on the top of React and Redux designed to reduce the boilerplate. Perhaps Vue2 will be what I'm after

The idea is very much like knockout and meteor, but the reactivity implementation is completely different. First all it is generic and not designed for just the UI. MobX is completely glitch free and synchronous and has explicit distinction between computed values and reactions (side effects like updating the DOM). More important, MobX determines the right execution other of derivations on the fly, preventing issues with 'double runs' which were a common issue in for example Meteor. These design decision are based on research of common issues with knockout and meteor (like the ones you described) and analyzing what is the root cause of these issues. For that reason you also won't find two way binding in MobX

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)

> MobX is completely glitch free

MobX looks interesting but I am a little concerned that you are claiming it is bug-free.

I don't believe he meant glitch in the sense of bugs but rather in FRP terms. I.e. temporarily inconsistent state.

yep that was the glitch I was referring to indeed :)

I don't know what you call a "very large" app, but I have a fairly complex app relying solely on Knockout with hundreds of observables/computeds being triggered in real-time to update the state of the UI as users drag and drop visual elements and it works like a charm. The UI is never out of sync with the model. I'm using Knockout 3.0, maybe things improved since you wrote your app?

I have written a fairly big open source React + Redux application https://github.com/rwieruch/favesound-redux and refactored it to use MobX instead of Redux https://github.com/rwieruch/favesound-mobx I hope I can add some extra value to your post.

I agree that for most users Redux feels like a lot of boilerplate. At the same time I think most people underestimate were we came from. Personally I wrote a huge amount of Angular code before and at a certain point I felt very unhappy about the two-way data binding and state handling in Angular. It was unpredictable in a huge code base at some point. Then it was the time of Flux and in our company we introduced a stores and unidirectional data flow implementation of our own. Afterwards Redux got announced and we loved the clear constraints and lightweight API from the beginning. We use it now.

In a team of developers everyone can clearly follow state changes, the state itself and the places from where the state changes were triggered. Redux is scaleable and shouldn't be used for every small project which could live without a state management library and should use setState instead. Redux simply works, even though you have already a big amount of actions in production.

I think MobX is on the right path to give an alternative way for state management. For now I see a clear benefit to kick off smaller projects in smaller teams which don't rely on Redux' constraints and scaleability. Little feature op-tins like useStrict will help MobX to have a more scalable state management system. Otherwise in a growing code base it will feel like the old Angular days with two-way data binding. In the end that is the power of MobX, because it isn't opinionated: You can either mutate your state directly in a component or build a proper infrastructure around it to make it scale.

Wow, your project looks great! I will be using it for inspiration in the future for mobx!

If selectors and reducers are a big pain for you, might I recommend the following library: https://github.com/mboperator/redux-modules

The motivation was to reduce boilerplate and improve the readability of redux state transformations. I've found that the number of files I need to touch to create an action drastically decreases.

At this point most of my development time is spent either in the module, the handler, or the saga.

React and Knockout are different because of how they render to the DOM, not because of computeds and observable concepts. KO is glitchy in big apps because it's working with and modifying the actual browser elements. And React is a view renderer without strict requirements on how the data is modeled. It seems like a great fit for benefits from both.

Mobx is a blessing ! I work on React only since a few months, I have a ton of subjects to learn, a ton of libraries to learn to how to use them. I really don't have time to learn a complex library like Redux. I tried, and learned its principles, but I soon saw that it would totally transform my existent codebase into a large cream cake with some boilerplate code everywhere. I come from Java world, which is often mocked (especially by the JS community ...) for its abstract-factory-factory, but Redux is not irreproachable for that ! Compared to Redux, MobX is a breath of air. It's very simple, very efficient, and contrary to Redux, not opiniated. It's easy to integrate it in an existing app. At the beginning, I only used MobX in a complex part of my app. I added a store, some instructions, and voilà. Then I added it everywhere, part by part, incrementally. Everything works, my code is simple, anybody, even a beginner, can understand it. MobX seems to be directly integrated in React.js, linked to the React core.

I haven't used Moxb but I've used Redux a lot the last 6 months, building mobile apps and also a rewrite of our frontend at Typeform.

I'm not sure how Redux could be considered complex, the API is very small and the ideas are small as well. There is really not much to learn with Redux. Redux is like literally 100 lines of code if you remove comments and simple sanity checks.

Also, not sure what you mean with boilerplate? What kind of boilerplate do you have when using Redux? Would love to see an example of that.

Personally I found that using redux for everything ends up spreading a ton of boilerplate everywhere. Action creators, reducer, the dumb component itself, the HOC.

All that adds up and is a lot of work for a simple component.

We ended up going with a hybrid setup. Our components are all dumb, and our "pages" are the only connected components. We also started using ducks[1] instead of spreading the reducer/actions everywhere whenever it makes sense.

[1] https://github.com/erikras/ducks-modular-redux

Redux isn't conceptually complex, but I found it hard to get started with. The trouble I had wasn't the ideas, which are very clear, but in trying to predict which parts (composing reducers, passing state to components) would be animated by Javascript magic, and which were plain-ol-Javascript.

I found myself straining a little to memorize code snippets to get things started.

Once up and running, it's a breeze, though of course I agree with the common sentiment that it's too easy to overuse, and native React state too easy to underuse.

It gets really hairy when you have to weave in asynchronous actions and things like react-thunk or react-saga. By the time you've wrapped your head around those concepts as well the whole React stack doesn't feel quite as much like the breath of fresh air it does when you first start using it.

For my next Resct project I intend to go as far as I can with simple container components before I start pulling in the whole Redux toolkit.

This is why Ryan Florence (react-router, React Training) just made his keynote speech at the React Rally conference about people overusing Redux and not learning or wanting to use plain old React.

In his trainings he constantly sees people trying to rush React and asking him about Redux (which he doesn't cover).

This is also a drum that Dan Abramov (who created Redux) has been beating.

It's interesting, I didn't find -thunk all that hard to grok, and in practice I was far less annoyed by that than I was by connect(). But I also found -thunk a refreshing change from what I'd been doing prior to redux (Flummox with async-await action creators).

Redux isn't complicated, it is the ecosystem around it which can be overwhelming or partly overengineered.

When you get started with React, you should use setState. You should use it until you get the feeling you really need a state management library to deal with most of the setState implementations. That removes the urge to learn another library next to React in the beginning.

Afterwards I agree: MobX is easier at the start, because it can be used similar like setState https://medium.com/@mweststrate/3-reasons-why-i-stopped-usin...

But at some point the developer team might decide to use MobX' useStrict to have more explicit actions and more predictable state changes. It removes the feeling of having two-way data binding and after all goes in the direction of the Redux constraints.

Adding some more:

Refactor a Redux Application to use MobX http://www.robinwieruch.de/mobx-react/

Large MobX React Application https://github.com/rwieruch/favesound-mobx

Thanks, you are the developer right? Great work!

I've been using this recently for a pretty complex SPA and it's been great.

It's clear what's happening, without a tons of boilerplate code, and it has some nice dev tools as well (trace element updates & events, great for debugging). It also has very useful error messages in development mode (which is a godsend).

On top of that, I think the docs are pretty good, they seem to be quite active on GitHub and, from every piece of the puzzle that comes together to make a 2016 web frontend (react, web pack, babel, flow, ui kit, etc, etc), it's given the least trouble for me so far.

I was able to rebuild a week's worth of Redux work in MobX within a day. And that's having never used it before.

What's crazy is how MobX is able to update React child components without updating the parent first. It knows which properties are accessed in each component, and ensures only the ones that rely on the changed data are updated.

I'd say give it a shot the next time you have a component with internal state. Not having to worry about the reducer or how the component gets updated is refreshing.

> It knows which properties are accessed in each component, and ensures only the ones that rely on the changed data are updated.

This is what blew me away. I understood that "computed" values were doing this, but when I saw that the react components were using it as well, I was sold. I have been in componentWillReceiveProps with redux too much, trying to improve rendering performance. With mobx, out of the box, you get 100% exact render updating.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact