본문 바로가기
프로그래밍/React Native(2018)

[React Native] mobX를 사용한 state management

by 쿼카퀀트 2019. 9. 29.
728x90

npm install mobx --save

npm install mobx-react --save

 

위 두 코드로 mobx를 설치한다.

 

 

 

설치가 끝난 후엔

 

프로젝트 폴더의 .babelrc를

"presets": [
  ["react-native"]
],
"plugins": [
  ["@babel/plugin-proposal-decorators", { "legacy": true }],
  ["@babel/plugin-transform-runtime", {
    "helpers": true,
    "polyfill": false,
    "regenerator": false
  }]
]

위처럼 플러그인을 적용(preset도 대괄호를 두번 적용해야 작동하는듯)

 

다음으로 package.json에서는 아래처럼 adevDependecies 내에 아래와 같은 디펜던시를 넣어준다.

"devDependencies": {
  "@babel/core": "7.0.0-beta.47",
  "@babel/plugin-proposal-decorators": "7.0.0-beta.47",
  "@babel/plugin-transform-runtime": "7.0.0-beta.47",
  "@babel/runtime": "7.0.0-beta.47",
  

이후 터미널에 npm install을 입력해 디펜던시에 맞는 파일들을 설치해준다.

 


*사용법

 

store 파일은 다음과 같이 만든다

계산이 필요없는 값은 @observable 을 붙여주고,

계산을 통해 값을 받는 경우엔 @computed get 을 붙여준다.

또한 아래서 보듯 addTodos(title)과 같은 메소드를 통해 내부 값을 수정해준다.

class storageTemp {
    @observable todos = ["buy milk", "fry some egg"];
    @observable filter = [""];
    @computed get valTemp(){
        let temp = "";
        for(let i=0;i<this.todos.length;i++){
            temp += this.todos[i]+","
        }
        return temp;
    }

    @action addTodos(title){
        this.todos.push(title);
    }
}

다음으론 이렇게 만든 storage 클래스를 new 로 생성한 후, {}로 묶어 이름을 지어주고 export default로 내보낸다.

const storeConst = new storageTemp;

export default {
    todoStore:storeConst,
}

 

 

*index.js 파일

 

index.js 에선 아래와 같이 Provider와 store - (위 storage.js에서 만든 export default {}에 랜덤하게 이름을 지어준 것) - 를 통해 아래와 같이 AppRegistry에 전달해 준다.

 

import React, {Component} from 'react';
import {
    Provider
}from 'mobx-react'
import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
import store from "./storage";

class AppTemp extends Component{
    render(){
        return(
            <Provider {...store}>
                <App/>
            </Provider>
        );
    }
}

AppRegistry.registerComponent(appName, () => AppTemp);

 

 


*실제 사용

 

실제 사용은 아래와 같이 만들어진다. inject, observer를 사용하며,

@inject(“불러오고자 하는 store이름”) 로 inject를 사용한다.

 

이렇게 inject를 하면 실제 클래스 내부에선 this.props.todoStore.~~~ 로 사용할 수 있게 된다.

import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View} from 'react-native';
import {inject,observer} from 'mobx-react'

@inject("todoStore")
@observer
export default class App extends Component {
    constructor(){
        super();

        this.state = {
            tempName:"Welcome!",
        };

    }

    render() {

        const todoList = () => {
            const listTemp = [];
            for(let i=0;i<this.props.todoStore.todos.length;i++){
                listTemp.push(
                    <Text
                        ref={comp => this.references = comp}
                        style={styles.instructions}>{this.props.todoStore.todos[i]}
                    </Text>
                )
            }
            return listTemp;
        };

        return (
            <View style={styles.container}>
                <Text style={styles.welcome}
                      onPress={()=>{
                          this.references.setNativeProps({
                              style:[styles.instructions,{backgroundColor:'red'}],
                          });
                          this.props.todoStore.addTodos("TT"),
                          this.setState({
                              tempName:"WOW",
                          })
                      }}
                >{this.state.tempName}</Text>
                <Text style={styles.instructions}>To get started, edit App.js</Text>
                <Text style={styles.instructions}>{this.props.todoStore.valTemp}</Text>
                <View style={styles.container2}>{todoList()}</View>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    },
    container2: {
        flexDirection:'column',
    },
    welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
    },
    instructions: {
        textAlign: 'center',
        color: '#333333',
        marginBottom: 5,
    },
});

 

또한, 만약 @observable 데코가 된 객체를 바로 return 하면 ObservableObjectAdministration를 return받는다. 이 경우 console.log를 통해 보기가 상당히 까다로워지기 때문에(활용하기에도),

 

import {toJS} from ‘mobx'

getWordbookById(wordbookID){
    for(let i=0;i<this.wordbook.length;i++){
        if(wordbookID === this.wordbook[i].id){
            return toJS(this.wordbook[i]);
        }
    }
    return undefined;
}

위처럼 toJS를 import해와 object로 만들고싶은 @observable 객체를 넣는다. 이렇게 하면 return에서 object를 받게 해준다.

728x90

댓글