Mobx is state management solution that is gaining popularity very fast. I'll show you
how to create a simple React-Native app using Mobx.
I strongly recommend to check this article on original website, because I have interactive examples there: maksimivanov.com
What Are We Going To Build
I have a few crypto coins on some exchanges. Not like I'm trading or something, I just bought some tokens that I liked and now just hold them and buy/sell ocasionally.
On Binance you can see how many coins you have and what's their worth in bitcoin and even in dollars, but you can't see what's the difference since the last time you've checked it.
We are going to build portfolio tracker for it. On first run we'll save all the coins prices and then we'll show the difference.
It'l look somewhat like this:
We'll learn how to store data locally, use flatlist, navigator and do multi-screen applications, also we'll learn how to manage state using mobx.
Table Of Contents
Why Mobx?
MobX is usually faster than Redux, requires less boilerplate and in general it's easier to grasp for novice.
Mobx has very few core concepts:
Observables
Observables allow you to subscribe for their changes. You can annotate your class properties with @observable
decorator and then track their values with observers
. So every time the values will change – observers
will be updated accordingly.
Here is simple example. It's a rolling dice – every time you press ROLL button – it re-rolls the dice and displays resulting number from 1 to 6.
import React, { Component } from 'react'
import ReactDOM from 'react-dom';
import { observable } from 'mobx';
import { observer } from 'mobx-react';
@observer class Dice extends Component {
@observable value = 1;
render() {
return (
<div style={this.styles.container}>
<div style={this.styles.result}>Result: {this.value}</div>
<button onClick={this.handleRoll}>ROLL</button>
</div>
)
}
handleRoll = () => {
this.value = Math.floor(Math.random()*6) + 1;
}
styles = {
container: {
padding: '16px 0px'
},
result: {
fontSize: 22,
marginBottom: 10
}
}
}
ReactDOM.render(<Dice />, document.getElementById('dice'));
Here was interactive example on original website
Computed values
Computed values can be derived from observables and will be updated automatically when the latter will be changed. Keep in mind, that in order to be updated computed
has to be observed.
@computed get computedValue() {
return this.value > 3 ? 'WIN' : 'LOOSE'
}
render() {
return (
<div style={this.styles.container}>
<div style={this.styles.result}>Result: {this.value}</div>
<div style={this.styles.result}>Computed Result: {this.computedValue}</div>
<button onClick={this.handleRoll}>ROLL</button>
</div>
)
}
Here was interactive example on original website
Reactions
Reactions are very similar to computed values but instead of returning new value they are used to produce side-effects (making network requests, patching dom e.t.c)
Mobx provides 3 types of reaction functions when, autorun and reaction
-
when
accepts two functions: predicate and effect. It runs and observes predicate until it returnstrue
, and then runs theeffect
function. After thet it disposes, and stops reacting observed property. -
autorun
is for cases when you need reactive function that will fire every time the observed value is updated. Unlikecomputed
it doesn't have to be observed itself. -
reaction
is likeautorun
but gives you more control over what properties to observe. It accepts two functionsdata-function
andside-effect-function
.data-function
is tracked and returns data that is used inside-effect-function
.
Here is an example of autorun
:
constructor() {
super();
autorun(
()=> (this.value > 3) && alert('WIN')
)
}
Here was interactive example on original website
Actions
Actions are anything that alters the state. So you can use them to explicitly mark that functions with @action
decorator.
This decorator takes function and wraps it into transaction
, untracked
and allowStateChanges
.
-
transaction
is used to batch state updates so no observers will be notified until that function is completed. So you can update multiple properties at once. -
untracked
allows you to run code without establishing observers (just like reactions, or unlike computed's) -
allowStateChanges
is used to allow/disallow state changes for certain function. By default allowsaction
to make changes (and disallows forcomputed
andobserver
).
Observers
Strictly speaking observers
aren't part of mobx core. They are provided by the mobx-react
package. But anyway…
They are used to make your views "observe" observables
and re-render on change.
But I'll cover it in next part.
Top comments (4)
Hi, nice article.
I would appreciate if you will share a code on a github. I am in the middle of Pluralsight's courses about angular and this seems very familiar to me now :) It will be a nice exercise to compare differences.
Thanks in advance.
Hey, great idea, will do in the end of the last article.
I think the title threw me off. I was looking for React Native examples. Although it appears that the mobx code will work the same with React Native.
guess it's reactjs example, not react-native