본문 바로가기
React Native/General

[React Native] MobX 도입 10분 컷!

by Juzero 2022. 1. 7.

1. mobx 도입 배경

 

안녕하세요. 제가 개발중인 영단어 앱은 하나의 파일 안에서 'screenMode' 상태값에 따라 화면을 바꿔주고 있습니다. 

 

screenMode === 'selectVoca'일 때는 왼쪽 화면이,

=== 'quiz'일 때는 오른쪽 화면으로 변경됩니다. 

 

 

지금까지는 한 파일 안에서만 바뀌니 useState를 사용해왔었는데요.

개발을 하다보니 이 파일, 저 파일에서도 screenMode를 참조해야할 일이 생겨버렸습니다..!

 

처음에는 props로 넘겨주고, 또 넘겨주고 했는데... 너무 복잡해서 ㅠ

 

mobX를 도입하기로 결정했습니다. 

 

 


 

2. React Native에 mobx를 적용하는 방법 및 과정

 

* 저는 함수형 코드를 사용하기 때문에 클래스형 코드로 개발하시는 분들과는 많이 다를 수 있습니다. 

* 아래 예시에서는 한개의 store파일만 생성했지만, 제 코드들은 여러개의 store 파일을 사용하는 구조입니다. 따라서, 기본적인 mobx 예시보다 조금 더 복잡할 수 있습니다.

* 하지만, 한 번 적용하면 활용이 너무나 쉽다는 것

 

1) 라이브러리 설치 및 설정

- mobx에 필요한 라이브러리를 설치해줍니다.

설치 후 꼭!  cd ios > pod install

 

npm install mobx --save
npm install mobx-react-lite --save

 

- 프로젝트 폴더의 루트 디렉토리에 .babelrc 라는 파일을 만들어주고 아래 코드를 붙혀넣습니다. 

{
    "plugins": [
        ["@babel/plugin-transform-flow-strip-types"],
        ["@babel/plugin-proposal-decorators", { "legacy": true}],
        ["@babel/plugin-proposal-class-properties", { "loose": true}]
    ]
}

 

 

 

이제부터 mobx 적용을 위한 폴더구조와 파일들을 만들어보겠습니다.

mobx에 필요한 폴더는 store, utils, hooks 이렇게 3개입니다. 하나씩 만들어가보시죠!

 

 

2) store 폴더 및 파일 생성

 

- src 디렉토리에 store 폴더를 만들고, 그 안에 index.js와 사용될 목적의 store.js 파일을 만들어줍니다.

 

아래 사진은 제 폴더 구조인데요. 저는 screenMode에 관한 상태를 관리할 것이기 때문에 screenModeStore.js라고 이름지었습니다. 

 

 

- store/index.js에 아래 코드를 붙혀넣습니다. import 부분과 가운데의 screenModeStore는 본인의 파일명으로 넣어주세요!

import screenModeStore from 'store/screenModeStore'

const createRootStore = () => {
  return {
    screenModeStore
  };
};

export default createRootStore;

 

 

- store/screenModeStore.js 파일을 작성합니다. 아래는 제 코드이고, 가장 기초적인 구조입니다. 

 

> observalbe은 우리가 관리할 상태값에 붙혀주는 속성입니다. 

> runInAction은 상태값을 변화시키는 코드에 붙혀주는 속성입니다. 

> observable.box()를 통해 해당 변수에 들어갈 초기값을 설정할 수 있습니다.

 

 

코드가 복잡해보여도, 구조적으로 보면 [상태값, 상태를 변화해주는 함수] 로 간단합니다.

import { observable, runInAction } from 'mobx';

const createStore = () => {
    const screenModeStore = {
        screenMode: observable.box('selectVoca'),

        changeScreenMode: (data) => runInAction(()=> screenModeStore.screenMode.set(data))
    };

    return screenModeStore;
};

const store = createStore();
export default store;

 

 

3) utils 폴더 및 context.js 파일 생성

 

src 디렉토리에 utils 폴더를 만들고, 그 안에 context.js라는 파일을 만들어줍니다.아래 코드를 context.js에 붙혀넣습니다. 

 

import { useLocalObservable } from 'mobx-react-lite';
import React, { createContext } from 'react';

import createRootStore from '../store/index';


export const storesContext = createContext(null);

export const StoreProvider = ({ children }) => {
  const store = useLocalObservable(createRootStore);

  return <storesContext.Provider value={store}>{children}</storesContext.Provider>;
};

 

 

4) hooks 폴더 및 useRootData.js 파일 생성

 

hooks 폴더를 만들고 그 안에 useRootData.js 라는 파일을 만들고 아래 코드를 넣어주세요.

import { useObserver } from 'mobx-react-lite';
import React, { useContext } from 'react';
import { storesContext } from 'utils/context';


export const useStoreData = (
  context,
  storeSelector,
  dataSelector,
) => {
  const value = useContext(context);
  if (!value) {
    throw new Error("No store");
  }
  const store = storeSelector(value);

  return useObserver(() => {
    return dataSelector(store);
  });
};

export default (dataSelector) => {
  return useStoreData(storesContext, (contextData) => contextData, dataSelector);
};

 

 

 

4) index.js 수정

가장 최상위 디렉토리에 있는 index.js를 수정해야 합니다. 

 

 

아래에서 주석으로 //추가 및 //변경 이라고 적힌 부분을 본인의 코드와 비교해서 수정해주세요!

 

 

 

고생하셨습니다!! 이제 mobx 사용을 위한 셋팅이 끝났어요!

 

mobx를 실제로 사용하는 코드를 보여드릴게요.

 

 


mobx를 사용할 파일에 useRootData를 import 합니다.

import useRootData from 'hooks/useRootData';

 

지금까지는 주석처리된 useState를 이용해서 상태값을 관리했습니다. 

그리고 주석 코드 아래는 mobx를 실제 스크린에 적용하는 코드에요. 

 

useRootData는 우리가 hooks 폴더에서 작성했던거죠? useRootData의 인자로 우리가 사용할 store파일을 넣어야 mobx를 쓸 수 있습니다.

 

 

 

저는 store 폴더에 screenModeStore.js 하나만 있고 store/index.js의 createRootStore의 return값에도 screenModeStore 하나만 들어있기 때문에, 저렇게 하나만 인자로 들어있는 것입니다. (2개 이상의 store를 쓰는 법은 아래를 참고해주세요!)

 

 

screenMode는 screenModeStore에 있는 screenMode의 값을 가져옵니다.(get)

changeScreenMode에는 screenModeStore에 있는 changeScreenMode 함수를 가져옵니다. 사용할 때는 setScreenMode(value)와 똑같이 changeScreenMode(value)로 사용하면 됩니다. 

 

 

 

그럼 이제 여러 파일에서 props로 상태값을 전달해줄 필요 없이, 이렇게 중앙의 상태값들을 가져올 수 있습니다. 

한 파일에서 상태값이 변하면, 다른 파일에 있는 값들도 자동으로 바뀝니다(짝짝짝)

 

 


 

 

만약에 영단어 데이터도 mobx로 관리해야하고, store폴더에 vocaData.js라는 파일이 하나 더 만들었다고 가정해볼게요!

 

1) 그럼 store 폴더에 vocaDataStore.js 라는 파일을 하나 더 만들고

 

2) store/index.js에서 vocaDataStore를 Import 해주고 return에 추가합니다. 

 

3) 그 다음 실제 적용할 파일에서 useRootData의 인자로 vocaDataStore를 넣어주고 추가해주면 됩니다!

초기 세팅이 복잡했지만, 한번 세팅하고 나면 이렇게 확장하는게 너무 쉽습니다. 

 

 


내가 만든 앱 홍보

RN로 만든 주식, 코인 물타기 계산기, 수익률 계산기 앱

안드로이드>

아이폰>

 

UN인턴이 만든 영단어 퀴즈앱

안드로이드>

아이폰>