본문 바로가기

React/이론

[React] MobX - React에서 사용하기

카운터 만들기 

yarn add mobx mobx-react
import React, { Component } from "react";
import { observable, action, makeObservable } from "mobx";
import { observer } from "mobx-react";

class Counter extends Component {
  number = 0;

  constructor() {
    super();
    makeObservable(this, {
      number: observable,
      increase: action,
      decrease: action,
    });
  }

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

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

  render() {
    return (
      <div>
        <h1>{this.number}</h1>
        <button onClick={this.increase}>+1</button>
        <button onClick={this.decrease}>-1</button>
      </div>
    );
  }
}

export default observer(Counter);

setState, useState 없이 값을 바꿔주면 알아서 렌더링이 된다. 

observer가 observable 값이 변할 때 컴포넌트의 forceUpdate를 호출해서 자동으로 변화가 화면에 반영된다. 

 

최적화가 많이 되어 있어 성능상의 문제도 크게 걱정할 필요가 없다. 

 

MobX 스토어 분리시키기

MobX에는 스토어라는 개념이 있다. 

Redux는 하나의 앱에 하나의 스토어만 있지만, MobX는 여러개를 만들어도 된다. 

스토어 만들기 

import { observable, action } from "mobx";

export default class CounterStore {
  number = 0;

  constructor() {
    super();
    makeObservable(this, {
      number: observable,
      increase: action,
      decrease: action,
    });
  }

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

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

Redux 처럼 리듀서나, 액션 생성 함수 등이 필요하지 않고 하나의 클래스에 observable 값이랑 함수를 만들어주면 

이다. 

 

Provider, 프로젝트에 스토어 적용

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { Provider } from "mobx-react";                             -- 1
import CounterStore from "./stores/counter";                       -- 2

const counter = new CounterStore();                                -- 3

const root = ReactDOM.createRoot(document.getElementById("root")); 
root.render(
  <Provider counter={counter}>                                     -- 4
    <App />
  </Provider>
);

MobX에서 프로젝트에 스토어를 적용할 때는 Redux처럼 Provider라는 컴포넌트를 사용한다. 

 

1. MobX에서 사용하는 Provider이다. 

2. 만들어둔 스토어를 불러온다. 

3. 스토어 인스턴스를 만든다. 

4. Provider에 props로 넣어준다. 

 

useStore, 컴포넌트에 스토어 주입

import { useContext } from "react";
import { MobXProviderContext } from "mobx-react";

const useStores = () => {
  return useContext(MobXProviderContext);
};

export default useStores;

6버전이 아닌 이전 버전의 경우 inject라는 함수를 사용해야하는데 useStores 안에 useContext로 사용할 경우 

내부에서 알아서 바인딩이 된다. 

 

컴포넌트에서 사용하기 

import React from "react";
import { observer } from "mobx-react";
import useStores from "./hooks/useStores";

export default observer(function NewCounter() {
  const { counter } = useStores();

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

observer는 여전히 사용하지만, useStores를 통해서 쉽게 store에 접근이 가능하다. 

즉, 컴포너트는 인터페이스와 인터랙션만 관리하면 되고, 상태 관리 로직은 스토어로 분리되었다. 

 

깃허브 

https://github.com/SeoJaeWan/mobx-with-react

 

GitHub - SeoJaeWan/mobx-with-react

Contribute to SeoJaeWan/mobx-with-react development by creating an account on GitHub.

github.com

 

반응형

'React > 이론' 카테고리의 다른 글

[React] Redux - 기본편  (1) 2022.07.21
[React] MobX - 심화  (2) 2022.05.05
[React] MobX - 시작하기  (1) 2022.04.29
[React] import React from 'react'는 어디에 쓰일까?  (1) 2022.04.17
[React] Virtual DOM  (2) 2022.03.12