본문 바로가기
📌 Front End/└ React

[React] MobX 상태 관리 라이브러리

by 쫄리_ 2024. 9. 11.
728x90
반응형

📌 MobX (전역 상태 관리)

상태 관리 라이브러리여러 컴포넌트 간의 상태를 쉽게 관리할 수 있도록 돕는 도구입니다.

MobX는 전역적으로 상태를 관리할 수 있는 스토어(Store)를 제공하여,

상태를 한 곳에서 관리하고 필요할 때 접근할 수 있게 합니다.

이를 통해 컴포넌트 간에 상태를 계속 전달하지 않아도 되어 상태 관리가 간단해집니다.

 

 


📌 MobX 작동 원리

MobX는 단방향 데이터 흐름을 기반으로 작동합니다.

MobX에서의 상태 관리 과정은 다음과 같은 단계로 이루어집니다.

 

  •  Actions (액션) 
    상태를 변경하기 위한 함수
    사용자가 어떤 동작을 취하면 그에 따라 상태를 변화시키는 역할

  •  Observable State (관찰 가능한 상태) 
    MobX에서 관리하는 데이터
    이 데이터는 여러 컴포넌트에서 관찰될 수 있으며, 
    변화가 발생하면 이를 사용하는 컴포넌트가 자동으로 업데이트

  •  Computed Values (계산된 값) 
    Observable State가 변경될 때마다 자동으로 재 계산되는 값
    이 값들은 주로 상태로부터 파생된 데이터를 계산할 때 사용

  •  Reactions (반응) 
    Observable State의 변화로 인해 발생하는 부수 효과(Side Effects)
    예를 들어, 상태가 변경될 때마다 UI를 재 렌더링하거나
    특정 로직을 실행하는 등의 작업 수행

 


📌 React에 MobX 적용

MobX는 상태 관리를 도와주는 라이브러리입니다.

MobX v6부터는 데코레이터를 사용하지 않고,

makeObservable 또는 makeAutoObservable 사용하여 상태를 설정합니다.


✅ MobX 라이브러리 설치

React에서 MobX를 사용하려면

mobx와 함께 mobx-react-lite 또는 mobx-react설치해야 합니다.

npm i mobx mobx-react
# mobx-react 함수형컴포넌트와 클래스형컴포넌트 모두 지원
npm install mobx mobx-react

# mobx-react-lite 함수형컴포넌트만 지원
npm install mobx mobx-react-lite

 


✅ MobX 스토어 생성 (상태 관리)

MobX에서는 상태를 관리하는 스토어(Store) 라는 개념이 있습니다.
Redux는 하나의 앱에 하나의 스토어만 사용할 수 있지만,

MobX는 여러 개의 스토어를 만들 수 있어 각 기능별로 독립적으로 관리할 수 있습니다.


  • MobX 스토어 폴더 생성 (상태 관리 파일 모음)
    • 상태를 관리할 파일들을 모아두기 위해 "📁mobx" 새 폴더 생성
  • 스토어 클래스 생성 (상태 관찰 파일)
    • 상태를 관리하고 관찰하기 위해 "스토어 클래스 생성"
    • makeAutoObservable 사용해 상태가 자동으로 관찰될 수 있도록 설정합니다.
    • 예 : 📜counter.tsx
  • 스토어 내보내기 (📜index.tsx)
    • 여러 스토어를 한 곳에서 관리하기 위해 "📜index.tsx" 파일에서 각 스토어를 내보냅니다.
    • 폴더명만 적으면 기본적으로 index.tsx를 참조합니다.
      •  MobX 
        📁mobx/📜index.tsx 에서 스토어 내보내고, 
        컴포넌트에서 import stores from '../mobx';로 가져옵니다.
      •  Hooks 
        📁hooks/📜index.tsx 에서 훅 내보내고, 
        컴포넌트에서 import { useToggle, useClamp } from '../hooks'; 로 가져옵니다.

 

사용예시

✏️ 스토어 클래스 생성 (📜counter.tsx)

  • 생성자에서 makeAutoObservable(this); 사용하면, 
     number 속성  관찰 대상(observable)이 되고, 
     increment, decrement 메서드  행동(action)이 됩니다.
  • 메서드(increment, decrement)들이 number 값을 변경하면, 
    MobX는 이 상태 변화를 자동으로 감지합니다.
  • MobX를 사용할 컴포넌트(예: LowComponent)를 observer 함수로 감싸면, 
    observer(LowComponent)는 Counter 스토어의 number 값 변경을 자동으로 감지하고, 
    값이 바뀌면 자동으로 다시 렌더링됩니다.
import { makeAutoObservable } from 'mobx';

class Counter {
    number: number;

    constructor() {
        this.number = 0;
        makeAutoObservable(this);  // ▶ 상태와 메서드를 자동으로 설정
    }

    increment(value: number){
        this.number += value;      // 상태가 변경됩니다.
    }

    decrement(value: number){
        this.number -= value;      // 상태가 변경됩니다.
    }
}

export default Counter;

 

 

✏️ 스토어 내보내기 (📜index.tsx )

  • 각 스토어를 index.tsx에서 모아서 내보냅니다.
  • counter 스토어를 다른 컴포넌트에서 import하여 사용할 수 있습니다.
import Counter from './counter';

export default {
    counter: new Counter()
};

 

 


✅ 컴포넌트에서 MobX 스토어 사용

  • App 컴포넌트 (Provider)
    • <Provider {...stores}> 모든 스토어를 하위 컴포넌트에 전달합니다.
    • 예를 들어, stores가 { counter: new Counter(), one: new One() } 형태일 때, 
      자식 컴포넌트는 이 스토어들을 사용할 수 있습니다.
    • <Observer />는 Provider 하위에서 스토어를 사용할 수 있게 해줍니다.
  • inject와 observer 함수 (MobX 스토어 주입 및 상태 변화에 따른 컴포넌트 리렌더링)
    • const Observer = inject('스토어클래스명')(observer(스토어사용할컴포넌트명));
    • observer(LowComponent) 
      LowComponent를 observer로 감싸 상태 변화에 반응하도록 만듭니다.
    • inject('counter') 
      counter 스토어를 LowComponent에 주입하여 컴포넌트에서 사용할 수 있게 합니다.
  • LowComponent 컴포넌트 (MobX 스토어 사용)
    • Props에서 counter 타입을 정의합니다.
    • 주입받은 counter 매개변수를 사용하여 UI를 렌더링하고, 
      버튼 클릭 시 스토어의 메서드(increment, decrement)를 호출하여 상태를 변경합니다.
    • observer(LowComponent)를 사용하면, LowComponent가 counter 스토어의 상태 변화를 감지하고, 
      상태가 변경되면 자동으로 화면이 업데이트됩니다.
    • 타입스크립트에서 counter?는 
      inject('counter')로 나중에 전달될 수 있어 선택적으로 설정합니다.

🔎 inject, observer 함께 사용 이유

  • inject, observer를 함께 사용하는 이유는 두 가지 기능을 결합하기 위함
    1. inject 함수 필요한 MobX 스토어를 컴포넌트에 주입합니다. 
      이를 통해 컴포넌트는 특정 스토어의 상태와 메서드를 사용
    2. observer 함수 MobX 스토어의 상태 변화를 감지하고,  
      상태가 변경될 때 해당 컴포넌트를 자동으로 다시 렌더링

 

사용예시

✏️ 컴포넌트에서 MobX 스토어 사용 (📜app.tsx )

Provider를 사용하여 애플리케이션의 모든 스토어를 하위 컴포넌트에 전달,

inject와 observer를 통해 특정 컴포넌트가 그 스토어를 사용하는 설정을 하고,

마지막으로 실제 컴포넌트가 그 스토어를 사용하여 UI를 구성하는 순서

 

  • App 컴포넌트 (Provider)
  • inject, observer 함수 (MobX 스토어 주입 및 상태 변화에 따른 컴포넌트 리렌더링)
  • LowComponent 컴포넌트 (MobX 스토어 사용)
import React from 'react';
import stores from '../mobx';
import { inject, observer, Provider } from 'mobx-react';

// ▶ 'counter' 스토어를 LowComponent에 주입하고, 상태 변화를 감지하도록 설정
const Observer = inject('counter')(observer(LowComponent));

// ▶ Props 타입 정의: counter 스토어를 선택적으로 받을 수 있음
//    Props 인터페이스에서 counter 속성은 선택적, 타입은 stores.counter
interface Props {
    counter?: typeof stores.counter;
}

// ▶ LowComponent: counter 스토어를 사용하여 UI를 렌더링
function LowComponent({ counter }: Props) {
    return (
        <div>
            <button onClick={() => counter?.increment(1)}>증가</button>
            <button onClick={() => counter?.decrement(1)}>감소</button>
            <div>{counter?.number}</div>
        </div>
    );
}

// ▶ Provider로 모든 스토어를 하위 컴포넌트에 제공
export default function App() {
    return (
        <div>
            {/* stores 객체의 모든 속성(예: counter)을 Provider의 props로 전달 */}
            <Provider {...stores}>
                <Observer />
            </Provider>
        </div>
    );
}

 


 

 

728x90
반응형