ReactNative with Mobx

For 深JS

2018.08.28 by WinDy

李亚飞

连续创业者, 全栈开发工程师, 专注于 web app & native app.

作品: cywin(创业赢), 8020(八十二十), 角落等

Github:  @windy

A very simple & powerful native app development architecture

ReactNative with mobx

What is mobx?

Inspired by spreadsheets

  • observable state
  • computed value
  • reaction

An example from spreadsheet

See actual code for mobx

// a very simple mobx example
import { observable, computed, autorun } from 'mobx'

class A {
  @observable a = "a";
  @observable b = "b";
  @observable c = "c";

  @computed get sum() {
    return this.a+this.b;
  }
}

let classA = new A();

// output "ab"
autorun( ()=> {
  console.log(classA.sum);
})

// output "aab"
classA.a = "aa";

// nothing output
classA.c = "cc";

Apply `spreadsheet` into Front-end development

  • Simple
  • Scalable
  • High Performance

// counter_store.js

import {observable} from 'mobx'
import api from './api'

class CounterStore {
  @observable counter = 0;
  @observable remoteCounter = 0;

  constructor() {
  }

  increment() {
    this.counter++;
  }

  decrement() {
    this.counter--;
  }

  incrementAsync() {
    setTimeout(() => {
      this.counter++;
      }, 500);
  }

  getFromRemote() {
    api.get('/hello')
      .then( (r)=> {
        if(r.ok)
          this.remoteCounter = r.data;
        else
          this.remoteCounter = 'error';
      });
  }
}

const counterStore = new CounterStore;

export default counterStore;
// counter_screen.js
import React, { Component, PropTypes } from 'react'
import { Text, View, StyleSheet } from 'react-native'
import Button from 'react-native-button'
import { observer } from 'mobx-react/native'
import ApplicationStyles from '../styles'
import Icon from 'react-native-vector-icons/FontAwesome'

@observer
export default class CounterScreen extends Component {

  render() {
    return (
      <View>
        <Text>Clicked: <Text>{this.props.counterStore.counter}</Text> times</Text>
        <Button style={ApplicationStyles.button} onPress={() => this.props.counterStore.increment()}>
          |   +1   |
        </Button>
        <Button style={ApplicationStyles.button} onPress={() => this.props.counterStore.incrementAsync()}>
          |   +1 async  |
        </Button>
      </View>
    )
  }
}

An actual Todolist APP with react-native-mobx

Thinking in deep

Why need mobx?

UI program = state + View

`state` determine `View`

`View` trigger `action` to update `state` to update `View`

If no state


// a todolist app code snippet by jQuery only
// from: https://github.com/tastejs/todomvc/blob/gh-pages/examples/jquery/js/app.js

var App = {
  init: function () {
    this.todos = util.store('todos-jquery');
    this.todoTemplate = Handlebars.compile($('#todo-template').html());
    this.footerTemplate = Handlebars.compile($('#footer-template').html());
    this.bindEvents();

  },
  bindEvents: function () {
    $('#new-todo').on('keyup', this.create.bind(this));
    $('#toggle-all').on('change', this.toggleAll.bind(this));
    $('#footer').on('click', '#clear-completed', this.destroyCompleted.bind(this));
    $('#todo-list')
      .on('change', '.toggle', this.toggle.bind(this))
      .on('dblclick', 'label', this.edit.bind(this))
      .on('keyup', '.edit', this.editKeyup.bind(this))
      .on('focusout', '.edit', this.update.bind(this))
      .on('click', '.destroy', this.destroy.bind(this));
  },
  render: function () {
    var todos = this.getFilteredTodos();
    $('#todo-list').html(this.todoTemplate(todos));
    $('#main').toggle(todos.length > 0);
    $('#toggle-all').prop('checked', this.getActiveTodos().length === 0);
    this.renderFooter();
    $('#new-todo').focus();
    util.store('todos-jquery', this.todos);
  }
}

If state

export default class TodoStore {
	@observable todos = [];

	@computed get activeTodoCount() {
		return this.todos.reduce(
			(sum, todo) => sum + (todo.completed ? 0 : 1),
			0
		)
	}

	@computed get completedCount() {
		return this.todos.length - this.activeTodoCount;
	}

	addTodo (title) {
		this.todos.push(new TodoModel(this, Utils.uuid(), title, false));
	}

	toggleAll (checked) {
		this.todos.forEach(
			todo => todo.completed = checked
		);
	}
}

Mobx data-flow

Vs Redux

Vs Redux

  • Dispatcher
  • Reducer
  • Action
  • Middleware

X

High Performance

3 ~ 15 times faster usually

vs

mobx

redux

Next generation?

mobx VS Vue

mobx VS WEEX

mobx vs Cycle.js or Bacon.js

( Functional Reactive Program )

React Native Mobx template

  • Simple
  • Scalable
  • Hight Performance
  • lots of experences by `80percent`

+1

Star and fork it!!!

八十二十

AD

Thank you

github: @windy

ReactNative with mobx from zero

By Li Yafei

ReactNative with mobx from zero

  • 4,506