카테고리 없음

MobX - 데이터 전역 상태 관리

qloz 2022. 8. 23. 21:28
728x90

MobX란?

리액트에서 MobX를 사용하게 되면, props drilling을 막을 수 있으며, 전역으로 상태관리를 할 수 있다.

하나 혹은 다수의 stroe를 두고, 해당 store에서 state를 저장해둔다.

MobX의 상태관리 flow

  • Observable State(관찰 받고 있는 상태)
    • MobX를 사용하고 있는 앱의 상태는 Observable하다. → 관찰할 수 있는 상태
    • 사용하고 있는 상태는 변할 수 있으며, 만약에 특정 부분이 바뀌면 MobX에서는 정확히 어떤 붑누이 바뀌었는지 알 수 있다.
    • 원시적인 값, 객체, 배열 내부의 객체, 객체의 키
  • Computed Value(연산된 값)
    • 기존의 상태값과 다른 연산된 값에 기반하여 만들어질 수 있는 값
    • 성능 최적화를 위하여 많이 사용된다.
    • 어떤 값을 연산해야 할 때, 연산에 기반되는 값이 바뀔때만 새로 연산하게 하고, 바꾸지 않았다면 그냥 기존의 값을 사용할 수 있게 해준다.
  • Reactions(반응)
    • 우리가 특정 값을 연산해야 될 때에만 처리가 되는 반면에, Reactions은 값이 바뀜에 따라 해야할 일을 정하는 것을 의미한다.
    • 예를 들어서 Observable State의 내부의 값이 바뀔 때, 우리가 console.log(’ddd’)라고 호출할 수 있다.
  • Actions(액션; 행동)
    • 액션은, 상태에 변화를 일으키는 것을 말한다.
    • Observable State에 변화를 일으키는 코드를 호출한다. ⇒ 하나의 액션
    • 리덕스에서의 액션과 달리 따로 객체형태로 만들지는 않는다.

MobX는 리액트 종속적인 라이브러리가 아니며, 따로 쓸 수 있다.

// src/stores/CounterStore.js

import { makeAutoObservable } from "mobx";

class CounterStore {
  number = 0;

  constructor() {
    makeAutoObservable(this);
  }

  increase = () => {
    this.number++;
  };

  decrease = () => {
    this.number--;
  };
}

export default CounterStore;
// src/Counter.js

import React from "react";
import { observer } from "mobx-react";

const Counter = observer(({ counter }) => (
  <div>
    <h1>{counter.number}</h1>
    <button onClick={counter.increase}>+1</button>
    <button onClick={counter.decrease}>-1</button>
  </div>
));

export default Counter;
// src/App.js

import * as React from "react";
import Counter from "./Counter";
import CounterStore from "./stores/CounterStore";

const myCounter = new CounterStore();

const App = () => {
  return <Counter counter={myCounter} />;
};

export default App;

stores 폴더 내에서 CounterStore를 만들어주어, 현재 state는 num이다.

증가 및 감소 action함수를 만들어주고, 각 기능을 추가해준다.

Counter컴포넌트에서는 observer를 통해 counter이 변하는지 체크한다.

Counter컴포넌트는 App.js에서 불러오며, store를 props로 주는 방식이다.

MobX는 객체지향적인 면이 강하다.

현재 리액트 컴포넌트들은 함수형을 사용하고 있기 때문에, 조금 더 예쁘게 코드를 짜보자면,

store 컴포넌트는 class가 아닌 useStore 등의 hook으로 빼내는 것도 좋은 방법이다.

728x90