본문 바로가기

React.js/상태관리

React에서 mobx 사용해보기 2 (decorator)

반응형
SMALL

mobx 옛날 버전에는 decorator라는 걸 이용했다는데

지금은 첫번째 글에 있는것 처럼 사용하는걸 추천한다고 한다.

그래도 옛날 꺼 읽을 줄 알아야하니까 써봤다.

 

react에서 javascript로 쓰려면 webpack이랑 bable 설정하고

package 다운받아야할 것도 많은데, 잘 따라해봤다.

근데 typescript쓰면 그냥 된다고 한다.

맨아래 부분에 package.json이랑 webpack,babel 설정 내용 복붙해놓겠다.

 

아무튼 중요한 건 그거 설정하는게 아니다.

왜냐면 이젠 안쓰는걸 지향하기 때문이란다.

 

그래서 decorator라는 걸 쓰는 예전 방식은 뭐가 다른지 알아보자

 

 

[index.js]

 - store 인스턴스 만들어서 props로 App컴포넌트에 내려주는거 동일하

import React from "react";
import { render } from "react-dom";
import App from "./App";
import counterStore from "./counterStore";


const store = new counterStore();

render(
  <div>
    <App counter={store}/>
  </div>,
  document.getElementById("root")
)
 

 

[counterStore.js]

 - 원래 makeObservable(this, {여기에 observable, computed, action 들어갔는데} ) 그렇게 안쓴다.

 - @ 이거 통해서 뭔지 정해준다. 

import { action, computed, makeObservable, observable } from "mobx";

export default class counterStore {
  @observable count = 0;

  constructor() {
    makeObservable(this);
  }

  @computed get isNegative() {
    return this.count < 0 ? 'Yes' : 'No';
  }
 
  @action increase() {
    this.count++;
  }
 
  @action decrease() {
    this.count--;
  }
}

 

[App.js]

 - observer 로 감싸줬었는데 안한다.

 - 대신 @(엣싸인) observer 붙여놓으면 그냥 해당하는 컴포넌트에 적용된다고 한다.

import { observer } from 'mobx-react';
import React, { Component } from 'react'

@observer
export class App extends Component {
  render() {
    const myCounter = this.props.counter;
    return (
      <div style={{textAlign: 'center', padding: 16}}>
        카운트: {myCounter.count}
        <br /><br />
        마이너스?: {myCounter.isNegative}
        <br /><br />
        <button onClick={() => myCounter.increase()}>+</button>
        <button onClick={() => myCounter.decrease()}>-</button>
      </div>
    );
  }
}

export default App

 

 

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

볼사람만 보기

[.bablerc]

{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ],
  "plugins": [
      ["@babel/plugin-proposal-decorators", { "legacy": true }],
      ["@babel/plugin-proposal-class-properties", { "loose": false }]
      // MobX 4/5에서와 반대로, "loose"가 false여야 합니다!       ^
  ]
}

 

[webpack.config.js]

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  mode: 'development',
  // 시작점
  entry: {
    main: path.resolve(__dirname, 'src/index.js'),
  },
  // 웹팩 작업을 통해 생성된 결과물
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name][contenthash].js',
    clean: true,
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  },
  devServer: {
    static: {
      directory: path.join(__dirname, 'dist'),
    },
    compress: true,
    port: 3000,
    open: true,
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.html',
    })
  ]
}



 

[package.json]

{
  "name": "react-mobx-counter-decorator-app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server --hot --open",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "devDependencies": {
    "@babel/core": "^7.18.6",
    "@babel/plugin-proposal-class-properties": "^7.18.6",
    "@babel/plugin-proposal-decorators": "^7.18.6",
    "@babel/preset-env": "^7.18.6",
    "@babel/preset-react": "^7.18.6",
    "babel-loader": "^8.2.5",
    "babel-plugin-transform-decorators-legacy": "^1.3.5",
    "html-webpack-plugin": "^5.5.0",
    "webpack": "^5.73.0",
    "webpack-cli": "^4.10.0",
    "webpack-dev-server": "^4.9.3"
  },
  "dependencies": {
    "mobx": "^6.6.1",
    "mobx-react": "^7.5.2",
    "mobx-react-devtools": "^6.0.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

 

 

 

 

 

 

 

반응형
LIST