How we use MobX at Rate
This will be the first of a (hopefully) multi-part series about how we use MobX with React.js at Rate. For this article, I will go through the Why, and the How, we use MobX across our front-end projects.
So… What is MobX? Why do you use it?
MobX is a library that makes state management simple and scalable by transparently applying functional reactive programming (TFRP). While it is a standalone library, most people are typically using it with React.
React and MobX together are a great combination. React renders your application state by providing mechanisms to translate it into a tree of renderable components, and MobX will provide the mechanism to store and update the application state that React then uses.
State Management in MobX
MobX makes state management simple again by addressing the root issue: it makes it impossible to produce an inconsistent state. The strategy to achieve that is simple: Make sure that everything that can be derived from the application state, will be derived. Automatically.
MobX, when used with React, provides very optimal and unique solutions to common problems in application development. React provides mechanisms to optimally render UI by using a virtual DOM that reduces the number of costly DOM mutations. MobX provides mechanisms to optimally synchronize the application state with your React components by using a reactive virtual dependency state graph that is only updated when strictly needed and is never stale.
Without further ado, let’s take a peek at how front-end engineers at Rate start a new project.
Starting a new project
Note: I assume you already have a basic knowledge of React. If not, here’s the official React tutorial.
Start your new project with Create React App.
Note: npx comes with npm 5.2+ and higher, see instructions for older npm versions
npx create-react-app my-awesome-app
cd my-awesome-app
npm start
Then, open http://localhost:3000/ to see your app.
Now that we’ve have our basic React Application, let’s integrate it with MobX.
—
Rewire create-react-app to use MobX
Step 1: Install these npm packages
npm install --save-dev react-app-rewired
npm install --save mobx mobx-react react-app-rewire-mobx
Step 2: Create a config-overrides.js
file in the root directory, and add rewireMobX
in.
/* config-overrides.js */
const rewireMobX = require('react-app-rewire-mobx');module.exports = function override(config, env) {
config = rewireMobX(config, env);
return config;
}
Right now, your folder should look something like this -
+-- my-awesome-app
| +-- config-overrides.js
| +-- node_modules
| +-- package.json
| +-- public
| +-- README.md
| +-- src
3) Flip the existing calls to react-scripts
in npm
scripts
/* package.json */ "scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test --env=jsdom",
+ "test": "react-app-rewired test --env=jsdom"
}
Note:-
is remove, +
is add.
Tadah, now we’re ready to use MobX in our Create-React-App application.
Simple example of MobX in action
We’ll be writing several files, here. So go ahead and create these files within your my-awesome-app/src
directory
TodoStore.js
TodoView.js
Let’s write up our TodoStore.js
, which needs to have these basic functionalities
- Add tasks
- Get total count of completed and uncompleted tasks
/* TodoStore.js */import {
observable,
action,
computed,
} from 'mobx';class TodoStore {
@observable todos = []; @computed get completedTodosCount() {
return this.todos.filter(
todo => todo.completed === true
).length;
}
@computed get uncompletedTodosCount() {
return this.todos.filter(
todo => todo.completed !== true
).length;
} addTodo(task) {
this.todos.push({
task: task,
completed: false,
assignee: null,
});
}
}export default new TodoStore();
Let’s write up our TodoView
, which needs to have these basic functionalities
- Renders a checkbox with a title
- Checkbox should track if it is done, or not.
- On checkbox click, we should toggle it’s
completed
state.
/* TodoView.js */import React from 'react';
import {
observer,
} from 'mobx-react';@observer
class TodoView extends React.Component {
render() {
const todo = this.props.todo;
return (
<li>
<input
type='checkbox'
checked={todo.completed}
onChange={this.onToggleCompleted}
/>
{todo.task}
</li>
);
} // Toggles the state of the Todo item
onToggleCompleted = () => {
const todo = this.props.todo;
todo.completed = !todo.completed;
}
}export default TodoView;
So, what does observer
do?
observer
turns React (function) components into derivations of the data they render. When using MobX, all components render smartly but are defined in a dumb manner. MobX will simply make sure the components are always re-rendered whenever needed, but also no more than that.
—
Lastly, let’s remember to render them. In your App.js
file, add these lines at the top of the file to import MobX
, and the 2 files you’ve just written! Also, remember to make your App.js
an observer
as well!
/* App.js */import TodoStore from './TodoStore'
import TodoView from './TodoView'
import {
observer,
} from 'mobx-react';@observer
class App extends Component {
...
Next, let’s add a function to handle new Todos. Put this chunk on the same level as your render
function, within your App.js
class.
onNewTodo = () => {
TodoStore.addTodo(prompt('Enter a new todo:', 'Learn MobX'));
}
Lastly, let’s render the stuff we wrote. Replace your <p>
tag inside the template App.js
file.
...
</header>
<div>
<ul>
{TodoStore.todos.map(
(todo, idx) => <TodoView todo={todo} key={idx} />
)}
</ul>
<button onClick={this.onNewTodo}>New Todo</button>
</div>
<div>
<p>
Total items done: {TodoStore.completedTodosCount}
</p>
<p>
Total items not done: {TodoStore.uncompletedTodosCount}
</p>
</div>
Play around with your working prototype
There you have it! You now have a simple to-do app that has the following features
- Adding a new task
- Marking and unmarking a task as done.
- Track number of tasks that are done, and not done yet
Ending notes & Resources
And there you have it — A working, MobX <> React application. Woohoo!
This is but of course a very simple ‘Get your hands dirty project’. In later posts, I’ll share several other lessons, such as Containers/ Presentational Components design, how we structure our stores & use Providers, and also useful tools we use in our front-end projects here at Rate.
In case you got lost halfway, here’s a repository of what we had covered in this short article
https://github.com/rate-engineering/MobX-Tutorial-1
Other useful links and references
- MobX - https://github.com/mobxjs/mobx
- 10 Minute MobX tutorial - https://mobx.js.org/getting-started.html
- Create React App - https://github.com/facebook/create-react-app
- Rewiring Create-React-App to use MobX - https://github.com/timarney/react-app-rewired/tree/master/packages/react-app-rewire-mobx
Final Words
Rate is hiring and we’re looking to hire the best & brightest to join us. If you’re looking for meaningful & challenging work, we’re looking for software developers of all kinds, graphic designers, kick-ass marketeers and much more.