Skip to content

Mobx Overview

Yongku cho edited this page Feb 9, 2021 · 4 revisions

Quick Example

import React from 'react';
import ReactDOM from 'react-dom';
import { makeAutoObservable } from "mobx"
import { observer } from "mobx-react"

class Timer {
  secondsPassed = 0;

  constructor (){
    makeAutoObservable(this)
  }

  increase() {
    this.secondsPassed += 1
  }

  reset() {
    this.secondsPassed = 0
  }
}

const myTimer = new Timer();

const TimerView = observer(({timer}) => (
  <button onClick={() => timer.reset()}>
    Seconds passed: {timer.secondsPassed}
  </button>
));

function App() {
  setInterval(() => {
    myTimer.increase()
  }, 1000);

  return (
    <TimerView timer={myTimer} />
  )
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);

MobX on older JavaScript environments

제품이 Proxy를 미지원하는 환경에서 실행될 경우 useProxiesnever로 설정한다.

import { configure } from "mobx"

configure({ useProxies: "never" }) // Or "ifavailable".

Reactive React components

import React from 'react';
import {render} from 'react-dom';
import {makeObservable, observable, action, computed} from 'mobx';
import {observer} from 'mobx-react-lite'

class Todo {
  id = Math.random();
  title = "";
  finished = false;

  constructor(title) {
    makeObservable(this, {
      title: observable,
      finished: observable,
      toggle: action,
    });
    this.title = title
  }

  toggle() {
    this.finished = !this.finished
  }
}

class TodoList {
  todos = [];
  get unfinishedTodoCount() {
    return this.todos.filter(todo => !todo.finished).length
  }
  constructor(todos) {
    makeObservable(this, {
      todos: observable,
      unfinishedTodoCount: computed
    });
    this.todos = todos
  }
}

const store = new TodoList([
  new Todo("Get Coffee"),
  new Todo("Write simpler code")
]);

const TodoListView = observer(({todoList}) => (
  <div>
    <ul>
      {
        todoList.todos.map(todo => (
          <TodoView todo={todo} key={todo.id} />
        ))
      }
    </ul>
    Tasks left: {todoList.unfinishedTodoCount}
  </div>
));

const TodoView = observer(({todo}) => (
  <li>
    <input
      type="checkbox"
      checked={todo.finished}
      onChange={() => todo.toggle()}
      />
    {todo.title}
  </li>
));

function App() {
  return (
    <TodoListView todoList={store} />
  )
}

render(
  <App />,
  document.getElementById('root')
);

Autorun

import {autorun, makeAutoObservable} from 'mobx';

class Animal {
  name;
  energyLevel;

  constructor(name) {
    this.name = name;
    this.energyLevel = 100;
    makeAutoObservable(this)
  }

  reduceEnergy() {
    this.energyLevel -= 10
  }

  get isHungry() {
    return this.energyLevel < 50
  }
}

const giraffe = new Animal("Gary");

autorun(() => {
  console.log(`Energy level: ${giraffe.energyLevel}`)
});

autorun(() => {
  if (giraffe.isHungry) {
    console.log(`Now I'm hungry!`)
  } else {
    console.log(`I'm not hungry!`)
  }
});

console.log(`Now let's change state!`);

Array
  .from({length: 10}, () => {
    giraffe.reduceEnergy()
  });
Energy level: 100
I'm not hungry!
Now let's change state!
Energy level: 90
Energy level: 80
Energy level: 70
Energy level: 60
Energy level: 50
Energy level: 40
Now I'm hungry!
Energy level: 30
Energy level: 20
Energy level: 10
Energy level: 0
Clone this wiki locally