._ _ _
| \ | | ___ | |_ ___ ___
| \| |/ _ \| __/ _ \/ __|
| |\ | (_) | || __/\__ \
|_| \_|\___/ \__\___||___/
MobX is an app state manager (used in place of something like Redux)
UPDATE: Below are fairly old notes at this point. Honestly, just read Mobdux: Combining the good parts of MobX and Redux. It is the best MobX article I've read!
- [Video: 3 mins] Mobx and React intro
- MobX: Ten minute introduction to MobX and React
- Note: the official docs are also great! Thorough and digestible.
Yes and no. In MobX, anything can counter++
an observable to change it's state. This kept many people away from trying MobX - we like the predictability of one-way, top-down actions updating our state. Fortunately, MobX responded to this community ask by introducing @action
and mobx.useStrict()
. See MobX 2.2: explicit actions, controlled mutations and improved DX for more.
- MobX tutorial #1 - MobX + React is AWESOME - YouTube
- MobX tutorial #2 - Computed Values and Nested/Referenced Observables - YouTube
- Becoming fully reactive: an in-depth explanation of MobX — Medium
- "mobx observable is really like "thing that notifies observers when it changes". You don't subscribe to them" - @15lettermax
- A MobX introduction and case study - We Are Wizards Blog
- Goes in to Typescript and mobx vs redux/immutable
- Michel Weststrate on Twitter: "Bunch of excellent tips on how to scale MobX applications: https://t.co/0imjjYENUo by @KatSickk"
- Actions, observable state, computed property values, reactions
- Strive for the smallest possible state. Derive the rest.
- Computed: like formulas in spreadsheets
- Not allowed to produce side effects
- types of reactions:
observer
,when
,autorun
- these have side effects
- With an observable array of objects, for example, MobX will automatically make the objects observables. This means child components of the list may need to be Observers to react to the object changes.
- mobx-examples: A collection of simple mobx examples
- Note, click on the links in the README to see the examples run in jsfiddle
- Mobx + Form Validation
- A React-Native app to remote control Google Play Music Desktop
- RFX Stack - Universal App featuring: React + Feathers + MobX
- google-play-music-desktop-remote: A React-Native app to remote control Google Play Music Desktop
- mobx-ssr-example: Server-side rendering with mobx and react-router
- MobX React: Refactor your application from Redux to MobX - RWieruch
- Any computation is deferred until needed by I/O. Huge performance benefits. Simplifies GC. - @mwestrate
- Observables benchmarked faster than Immutable. tweet
- mobxjs/react-particles-experiment: An experiment to see if you can make a particle generator in redux+react+d3.
- Stores: Separate your ui-stores (forms, navigation, modals) and domain-stores (models). See Defining data stores.
- "If you want to update some observables automatically (e.g. in autorun), you probably should use computed instead" - mweststrate
- If already using mobX for app state, consider using it in place of React'
setState()
: see 3 Reasons why I stopped using React.setState — Medium - To enforce this, use the no-set-state eslint rule
- from @jay_soo
- Redux uses Pure Functions.
- MobX uses Reactive Programming.
- Reactive Programming is making your functions react to events they are listening in to, rather than making your buttons (components), http requests, and all other parts of your application call your functions. - video
- Flux (Redux) is designed to answer the question: when does a given slice of state change, and where does the data come from? It is not designed to be the most performant, or the most concise way of writing mutations. Its focus is on making the code predictable. - Dan Abramov
- Redux con: It is kinda strange in Redux to see
<Something/>
in a render with no props but then has some required propTypes and gets them. - @ryanflorence
- Not really. See this thread for some responses: https://twitter.com/DonHansDampf/status/735339826984128513
Using the MobX @action decorator with async functions and .then
- I haven't tried this, but see https://gist.github.com/rej156/4524b59ea77a697fb62a39eada5b9bbe from this tweet
Example store from Janiczek:
class Store {
/**********************************
* BASE VALUES
**********************************/
@observable bpm = 120;
@observable playing = false;
/**********************************
* COMPUTED VALUES
**********************************/
@computed get msPerClick() {
return 60000 / this.bpm;
}
@computed get playButtonIcon() {
return this.playing ? 'stop' : 'play';
}
@computed get bpmString() {
return (this.bpm) ? this.bpm.toString() : '';
}
/**********************************
* ACTIONS
**********************************/
@action togglePlaying() {
this.playing = !this.playing;
}
@action setBpmFromString(bpmString) {
this.bpm = parseFloat(bpmString) || null;
}
@action clampBpm() {
this.bpm = clamp(this.bpm, 1, 999.999);
}
}
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import {observable} from 'mobx';
import {observer} from 'mobx-react';
import DevTools from 'mobx-react-devtools';
const appState = new class AppState {
@observable timer = 0;
constructor() {
setInterval(() => {
appState.timer += 1;
}, 1000);
}
resetTimer() {
this.timer = 0;
}
}();
@observer
class TimerView extends Component {
render() {
return (
<div>
<button onClick={this.onReset}>
Seconds passed: {this.props.appState.timer}
</button>
<DevTools />
</div>
);
}
onReset = () => {
this.props.appState.resetTimer();
}
};
ReactDOM.render(<TimerView appState={appState} />, document.getElementById('root'));
Same as what is shown in Web's Debugger, but import { observer } from 'mobx-react/native'
instead of just from mobx-react
There are no official native dev tools yet. You can, however, log each action with something like this in your app.js
:
// log all mobx actions when in development mode
if (__DEV__) {
mobx.spy( ev => {
if (ev.type === "action") {
console.log( ev.name )
}
})
}