Case — Mobx to Redux
Today I'm going to share a case study about a migration from Mobx to Redux and the reasons my team and I considered when making this decision.
I see many questions about which is better, what to use in a large-scale project, and the pros and cons of each technology. There were many questions, and after a lot of study we carried out the migration.
Below I'll describe some of the points that helped us make this decision.
Ah… just a heads up: there is no one-size-fits-all recipe. Each project has its own needs and this should be evaluated by the entire team.

On a project I worked on at Zup, our product had been in production for about 1 year and we were using Mobx to manage its state.
With Mobx it's possible to create a store and control your page state through @observables. Here is the flow:

Mobx works in an extremely simple way — it's almost plug-and-play. As @Michel Weststrate himself says, React + Mobx is a powerful combination. The tool truly offers many features for controlling our pages.
With observables we can maintain the following structure:
index.js (view)
store.js (where all the logic and page control live, state changes, etc.)
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import {observer} from 'mobx-react';
@observer
class TodoListView extends Component {
render() {
return (
<div>
<ul>
{this.props.todoList.todos.map(todo =>
<TodoView todo={todo} key={todo.id} />
)}
</ul>
Tasks left: {this.props.todoList.unfinishedTodoCount}
</div>
)
}
}
const TodoView = observer(({todo}) =>
<li>
<input
type="checkbox"
checked={todo.finished}
onClick={() => todo.finished = !todo.finished}
/>{todo.title}
</li>
)
const store = new TodoList();
ReactDOM.render(<TodoListView todoList={store} />, document.getElementById('mount'));
Notice how simple it is: we have TodoView with an observer HOC controlling the TodoListView page. To receive the props from the Store (TodoView), you just add an observer decorator to the view. To make the view receive the store, just pass it as a property ( todoList={store} ), beautiful!
Confused? Roughly speaking, it looks like this:

Of course, each event has its own full Life Cycle, as shown in the flow above.
Mobx has few concepts to make it easy to use and scale.
Well, everything was going fine, until… the team started growing a lot and so did the project, and then we started running into some problems.
1 — Global Dispatch 😢 2 — Propagating the store between components 😢 3 — Magic Methods 😢 4 — Very large stores 😢 5 — Issues with layer separation 😢 6 — Immutability 😢 7 — Scalability 😢
Without a doubt, our biggest problem was firing something in one component and propagating it to another without a lot of headaches. The issue is that with Mobx you need to keep passing the Store between components via props, and it's not possible to simply make a dispatch in one component and have another one on the other end listen and receive the values, as in an event-driven architecture. We wanted to send values from container A to B, but without passing through the others, as shown below:

This was generating a lot of headaches — the code was turning into spaghetti (if not well-structured). We had our controllers all living in each component's store, and this became a big problem.
Another major issue is that Mobx state is mutable — meaning every time we change our store, we are directly mutating our state, which can create many side effects.
That's when we looked into a solution and came across Redux, since its flow is different and, for our problems, it would fit well.
With Redux we managed to solve some problems =D
1 — Global Dispatch 👌 2 — Propagating the store between components 👌 3 — Magic Methods (no more) 👌 4 — Very large stores 👌 5 — Issues with layer separation 👌 6 — Immutability 👌 7 — Scalability 👌
Redux handles events with functional programming, which is great — providing more control over the application and the expected results, avoiding magic methods.
Our flow now looks like this:

We have a single store in the system, which is a huge advantage, since we can simply connect to any component/container and access the props in the store.

And the separation of responsibilities became cleaner — for example, we have reducers, types, and actions to separate the logic, making the view simpler. Of course the system became more verbose, but we managed to make things simpler and easier to maintain. But, just like Mobx or any other architecture, we need to keep things well-defined, otherwise the system will become a mess.
A famous quote from Dan Abramov is:
You Might Not Need Redux
That's right — you might not need Redux. If it makes sense for your system and is necessary, then use it; otherwise you'll have a big headache :)
Well, in addition to our changed flow, we now have immutability on our side. Unlike Mobx, Redux creates a new state for our application without touching the previous one, so we can know exactly what happened.
On top of that, we have debugging tools — redux-devtools — which record every step of every change. That's a huge advantage, since Redux works with functional programming and doesn't alter your application state directly.
Now, as not everything is perfect — remember I mentioned at the beginning that our application had already been in production for about a year? So, time for some refactoring :)
It wasn't just the introduction of Redux that improved our application. Since we had to refactor a lot of things, we took the opportunity to revisit our architecture and avoid mistakes we had made with Mobx — like assuming that everything should go in the store, when in reality plain React can solve most of our problems. Think about Flux.
Almost 100% of the application has already been migrated to Redux and the benefits were many. But I stress: it wasn't the simple act of switching libraries that solved our problems — it was a paradigm shift and a reorganization of the project.
The tools we use help a lot, but if they're not applied correctly, they'll only create more problems.
We chose this migration because of a specific need we had.
But before any change, check whether it's truly necessary — because many people choose one option or another simply out of trend, without really knowing the tools and their intended purposes, and often without even having a problem to solve.
So then, which is better — Mobx or Redux? Both! Each one solves problems in its own way. As I mentioned before, choose something that will solve your needs. Switching for the sake of switching will only cause more problems. The team's knowledge is also a very important factor when making this choice.
This applies to any lib/framework — don't fall for "this one is dead, that other thing is better, it came out today :)".
References:
https://github.com/mobxjs/mobx https://github.com/reactjs/redux https://reactjs.org/ https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367 https://codeburst.io/mobx-vs-redux-with-react-a-noobs-comparison-and-questions-382ba340be09
