Skip to content

Latest commit

 

History

History
199 lines (159 loc) · 9.58 KB

mobx.md

File metadata and controls

199 lines (159 loc) · 9.58 KB
._   _       _            
| \ | | ___ | |_ ___  ___
|  \| |/ _ \| __/ _ \/ __|
| |\  | (_) | ||  __/\__ \
|_| \_|\___/ \__\___||___/

MobX

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!


Getting Started

Uhhh, isn't this just 2-way data binding?

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.

Learning More

Some Main concepts

  • 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.

Examples

Performance

Best Practices

Structure

Patterns

Questions

What are the pros/cons versus Redux (flux)?

  • 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

Is there a router for MobX?

How to deal with Promises using useStrict()?

Using the MobX @action decorator with async functions and .then

Possible to use Hot Loader?

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);
    }
}

Web Setup/DevTools

from mobx-react-boilerplate

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'));

React Native Setup

Same as what is shown in Web's Debugger, but import { observer } from 'mobx-react/native' instead of just from mobx-react

Dev Tools

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 )
    }
  })
}

Resources