반응형

들어가기 전

  • Controller에서 값 증가, 하락 버튼을 클릭한 경우 Display에서 변경된 값을 출력
  • Controller에서 색변경 버튼을 클릭한 경우 Display에 배경색을 랜덤으로 변경

mobx란?

  • 상태, 이벤트를 글로벌하게 관리하는 방법 중 하나
  • redux와 비슷한 용도로 사용
  • 자바처럼 어노테이션을 활용

eject 처리

  • mobx 바벨 처리를 위해 이 과정이 필요함
npm run eject

mobx 설치

yarn add mobx mobx-react

babel-plugin 설치

yarn add @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators

package.json 모듈 설치 확인

"mobx": "^5.9.4"
"mobx-react": "^5.4.4"
"@babel/plugin-proposal-class-properties": "^7.4.4"
"@babel/plugin-proposal-decorators": "^7.4.4"

package.json babel 설정

"babel": {
    "presets": [
        "react-app"
    ],
    "plugins": [
        ["@babel/plugin-proposal-decorators", { "legacy": true}],
        ["@babel/plugin-proposal-class-properties", { "loose": true}]
    ]
}

Store.js 파일 추가

  • 경로 : <프로젝트>/src/store/Store.js
import { observable, action } from 'mobx';

export default class Store {
    @observable number = 0;
    @observable color = [255, 255, 255];

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

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

    @action setColor = (color) => {
        this.color = color;
    }
}

Display.js 파일 추가

  • 경로 : <프로젝트>/src/component/Display.js
import React, { Component } from 'react';
import PropTypes from 'prop-types';

const propTypes = {
    number: PropTypes.number,
    color: PropTypes.array
};

const defaultProps = {
    number: -1,
    color: [0, 0, 0]
};

class Display extends Component {
    render() {
        const color = this.props.color;
        const style = {
            background: `rgb(${color[0]}, ${color[1]}, ${color[2]})`
        };

        return (
            <div style={style}>
                <h1>{this.props.number}</h1>
            </div>
        );
    }
}

Display.propTypes = propTypes;
Display.defaultProps = defaultProps;

export default Display;

Controller.js 파일 추가

  • 경로 : <프로젝트>/src/component/Controller.js
import React, { Component } from 'react';
import PropTypes from 'prop-types';

const propTypes = {
    onPlus: PropTypes.func,
    onSubtract: PropTypes.func,
    onRandomizeColor: PropTypes.func,
};

const defaultProps = {
    onPlus: () => console.warn('onPlus is not defined'),
    onSubtract: () => console.warn('onSubtract is not defined'),
    onRandomizeColor: () => console.warn('onRandomizeColor is not defined'),
};

class Controller extends Component {
    render() {
        return (
            <div>
                <button onClick={this.props.onPlus}>+</button>
                <button onClick={this.props.onSubtract}>-</button>
                <button onClick={this.props.onRandomizeColor}>Randomize Color</button>
            </div>
        );
    }
}

Controller.propTypes = propTypes;
Controller.defaultProps = defaultProps;

export default Controller;

App.js 파일 추가 - 전체 props 받을 경우

import React, { Component } from 'react';
import { observer, inject } from 'mobx-react';
import Display from './component/Display';
import Controller from './component/Controller';

@inject('store')
@observer
class App extends Component {
  constructor(props) {
    super(props);

    this.setRandomColor = this.setRandomColor.bind(this);
  }

  setRandomColor() {
    const { store } = this.props;
    const color = [
      Math.floor((Math.random() * 55) + 200),
      Math.floor((Math.random() * 55) + 200),
      Math.floor((Math.random() * 55) + 200)
    ];

    store.setColor(color);
  }

  render() {
    const { store } = this.props;

    return (
        <div>
          <Display
              number={store.number}
              color={store.color}
          />
          <Controller
              onPlus={store.increase}
              onSubtract={store.decrease}
              onRandomizeColor={this.setRandomColor}
          />
        </div>
    );
  }
}

export default App;

App.js 파일 추가 - 일부 props를 받을 경우

import React, { Component } from 'react';
import { observer, inject } from 'mobx-react';
import Display from './component/Display';
import Controller from './component/Controller';

@inject(stores => ({
  number: stores.store.number,
  color: stores.store.color,
  increase: stores.store.increase,
  decrease: stores.store.decrease,
  setColor: stores.store.setColor,
}))
@observer
class App extends Component {
  constructor(props) {
    super(props);

    this.setRandomColor = this.setRandomColor.bind(this);
  }

  setRandomColor() {
    const color = [
      Math.floor((Math.random() * 55) + 200),
      Math.floor((Math.random() * 55) + 200),
      Math.floor((Math.random() * 55) + 200)
    ];

    this.props.setColor(color);
  }

  render() {
    return (
        <div>
          <Display
              number={this.props.number}
              color={this.props.color}
          />
          <Controller
              onPlus={this.props.increase}
              onSubtract={this.props.decrease}
              onRandomizeColor={this.setRandomColor}
          />
        </div>
    );
  }
}

export default App;

index.js 파일 수정

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

import { Provider } from 'mobx-react';
import Store from './store/Store';

const store = new Store();

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>,
  document.getElementById('root')
);

참고

반응형

'Development > React' 카테고리의 다른 글

[React] CSS Module  (0) 2019.05.16
[React] Hooks  (0) 2019.05.15
[React] Redux  (0) 2019.05.14
[React] 기본 문법  (0) 2019.05.05
[React] Visual Studio Code 설정  (0) 2019.05.05

+ Recent posts