Have fun with MobX and React (More reactive, less state)


I always like the concept of reactive programming, since they’re more intuitive and you can write less code, to do awesome things!

However, reactive programming always come with performance and memory penalty. It’s also damn hard to debug (as it’s non-deterministic).

But since we have powerful computers nowadays, and we have advanced debuggers, I guess we could neglect the cost of it, even on mobile, we usually have more than 4 cores, 2 gigs of RAM, and together they could compensate the performance loss, at least it won’t be sluggish and bloated, and we could also make sure no unintended side effects will come into our application.

With the dynamic and interpreter nature of JavaScript, we should encourage more reactive programming, to not only improve our life quality, but to also stay away from the endless boilerplates like what you’d face with Redux.

So far this is what I’ve found with MobX and React. I’ve created a stupid Todo prototype, yes, without any CSS decorations, with only shabby, basic features, and it’s also ugly as hell. But I guess it serves the demonstration purpose well. I do expect to expand my project into something more interesting, e.g. API abstraction, reactive updates, at least something useful in the future.

Here we will enter the journey. Watch it.


We will be using decorators. MobX originally, is intended to use with decorators in order to unleash its potential. But since Babel 6 removed it, we will have to re-enable it in our Babel configuration: (PS in Babel 7, decorator made a comeback!)


In .babelrc

{
"presets": [
"latest",
"react",
"stage-0"
],
"plugins": [
"transform-decorators-legacy"
],
}

In NPM:

npm install babel-core babel-preset-latest babel-plugin-transform-decorators-legacy babel-preset-latest babel-preset-stage-0 mobx mobx-react react react-dom webpack webpack-dev-server autobind-decorator

And that’s it, I won’t be detailing the configuration for Webpack, but be sure you made it working and it can serve web contents.


I’ll make my Todo component called App, and it was stored in App.js, and my DOM render bootstraper will be in index.js, which is also the JavaScript entry point for my prototype.

index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));

That’s it, no fancy stuff, just render please.

OK, so now we enter the main course here, our Todo App.

App.js:

import React, { Component } from 'react';import autobind from 'autobind-decorator'
import { observable, action } from 'mobx'
import { observer } from 'mobx-react'

Maybe you have observed autobind being imported here, yes, I don’t want to do all the .bind(this) stuff in our callbacks so I used it alongside my App class

@autobind
@observer
class App extends Component {

Here we have a observer component imported from mobx-react, this will mark our component dirty if a change in MobX observables is found, so it could proceed to issue a force update. Remember decorators are stack-based, so I placed autobind first so it will be the last to apply to the class.

Then we have our todos object:

@observable todos: Array<{
value: string,
finished: boolean,
}> = [];

Maybe the flow typing is an overkill, but it’s more expressible to me, so I let it remain.

Here we define an object array with a value string and a finished boolean to indicate whether or not it can be ‘eliminated’.

And we have of course observable to see if there’s any change. With the help of observable, we will never have to getInitialState and setState again. We could just do things on air, and the MobX system will handle the rest.

Sounds cool isn’t it? Well, this is even cooler:

render() {
return (
<div>
<h1>Todo App with mobx-react</h1>
<form onSubmit={(e) => e.preventDefault()}>
<ul>
{ this.todos.map((todo, index) =>
<li key={index}>
{todo.finished ? <s>{todo.value}</s> : todo.value}
<input type="checkbox" checked={todo.finished} onChange={ (e) => todo.finished = e.target.checked }/>
</li>
)}
</ul>
<input type="text" ref="todoEntry" />
<button onClick={ this._onButtonClick }>Add</button>
<button onClick={ () => this.todos.length > 0 && this.todos.pop() }>Remove Last</button>
</form>
</div>
);
}

Look, there’s no setState here, I could just assign my value and it’s good to go, already rendered. Besides, I could just fetch my value and they will be updated on-time. Amazing isn’t it?

I have missed the button click handler though:

_onButtonClick(e) {
let entry = this.refs.todoEntry
if (entry.value.length > 0) { // prevent empty inputs
this.todos.push({
value: entry.value,
finished: false
})
entry.value = "" // reset the input
}
}

Look again, I need not setState, MobX will handle the push call for me.

Although I haven’t exported it:

export default App;

That’s it! In 50 lines of code you get a simple (and dummy and phony) Todo prototype here, nothing else. Imagine the same thing with Redux, that is at least more than 100 lines of code!

See in action

I’m looking forward to creating a reactive Twitter clone with MobX and React, I’ll include live-update with Socket.io, you know, the dynamic nature of MobX makes it really easy to achieve this. MobX has its potential, just because the name and fame of Redux shifted developers’ attention, it doesn’t mean MobX is bad, I mean, MobX can go even beyond Redux!

But people still marketed Redux as the real-man’s tool where MobX is for little, I object this. I seriously object the fact that MobX is minor and handicapped. Redux is for the little man and prototype products, where MobX is the only true practice.

I’m also looking positive to seeing MobX going popular and mainstream. More incredible apps should be created from MobX. Besides we have React Native implementation, this is pretty perfect for a mobile app to go reactive.

Personally, I hated Redux, very hatred, all that boilerplate and configurations and bloats and stuffs makes me go bananas! MobX saved the day for me, you could just plug-and-play, and everything is so damn expressible! This is already paradise for me, and hopefully more developers will glance into the true aesthetic of MobX, and finally to obsolete the Redux headache!

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade