MobX Test

HTML

<script src="https://unpkg.com/mobx/lib/mobx.umd.js"></script>
<script src="https://unpkg.com/mobx-react"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react-dom.js"></script>
<script src="https://unpkg.com/mobx-react-devtools"></script>
<div id="root"></div>

CSS

button {
  margin: 4px;
}

Babel + JSX

// ——————————————————————————————————————————————————
// Dependencies
// ——————————————————————————————————————————————————

const { Component } = React;
const { observer } = mobxReact;
const { observable, action, computed, useStrict } = mobx;
const { render } = ReactDOM;
const DevTools = mobxDevtools.default;

useStrict(true);

const fetchBaz = () => new Promise(resolve => {
	setTimeout(() => resolve(Math.random()), 500 + Math.random() * 500);
});

// ——————————————————————————————————————————————————
// Store
// ——————————————————————————————————————————————————

class CounterStore {
  @observable count;
  constructor(count = 0) {
  	this.id = Math.random();
    this.count = count;
  }
  @action increment() {
    this.count++;
  }
  @action decrement() {
    this.count--;
  }
}

class ApplicationStore {
  @observable counters;
  @observable loading;
  @observable data;
  constructor() {
  	// In practice, use the @autobind decorator on the store class
  	this.removeCounter = this.removeCounter.bind(this);
  	this.reset();
  }
  @computed get total() {
    return this.counters.reduce((sum, counter) => sum + counter.count, 0);
  }
  @computed get dataJSON() {
  	return JSON.stringify(this.data, null, 2);
  }
  @action reset() {
  	this.loading = false;
  	this.data = {
    	foo: 'hello',
      bar: {
      	baz: [1, 2, 3]
      }
    };
    this.counters = [
      new CounterStore(1),
      new CounterStore(2)
    ];
  }
  @action addCounter() {
    this.counters.push(new CounterStore());
  }
  @action removeCounter(counter) {
		this.counters.splice(this.counters.indexOf(counter), 1);
  }
  @action updateBaz() {
  	this.loading = true;
  	fetchBaz().then(action(result => {
    	this.data.bar.baz.push(result);
      this.loading = false;
    }));
  }
}

// ——————————————————————————————————————————————————
// Components
// ——————————————————————————————————————————————————

@observer class Counter extends Component {
	constructor() {
  	super();
 ...