본문 바로가기
React를 같이 배워보자

React26일차-mobx-computed,action

by 멈추지않아 2022. 2. 20.

오늘은 computes action에 대해서 배워 보겠습니다. 어제 했던 것에서 이어서 하겠습니다

npm start도 같이해주세요

우선 computed에 대해서 배워보겠습니다.

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { makeObservable, observable } from "mobx";
class add {
  @observable
  add1 = 1;
  @observable
  add2 = 2;

  constructor() {
    makeObservable(this);
  }
  clicked() {
    this.add1 = this.add1 + 1;
    console.log(this.add1);
  }
  addcompute() {
    if (this.add1 > 10) {
      return 10;
    } else {
      return 0;
    }
  }
}
export const added = new add();

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

작성

App.js

import logo from "./logo.svg";
import "./App.css";
import { added } from "./index";
import { observer } from "mobx-react";
function App() {
  console.log("render");
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>{added.addcompute()}</p>
        <button onClick={click}>증가</button>
      </header>
    </div>
  );
  function click() {
    added.clicked();
  }
}

export default observer(App);

작성하고 

npm start해서 콘솔을 보겠습니다.

화면에서 창은 한번밖에 안바꼈어요 그런데  render는 add1이 바뀔때마다 render가 되요 이건 너무 낭비입니다.

즉 화면에서 데이터가 변활때만 render되게 하기위해 computed가 쓰입니다. 이제 한번만 render되게 바꺼보겠습니다.

index.js

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { computed, makeObservable, observable } from "mobx";
class add {
  @observable
  add1 = 1;
  @observable
  add2 = 2;

  constructor() {
    makeObservable(this);
  }
  clicked() {
    this.add1 = this.add1 + 1;
    console.log(this.add1);
  }
  @computed
  get addcompute() {
    if (this.add1 > 10) {
      return 10;
    } else {
      return 0;
    }
  }
}
export const added = new add();

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

addcompute위에 @computed 하고  앞에get을 붙여줘서 데이터를 가져올수 있게 해주었습니다.

App.js

import logo from "./logo.svg";
import "./App.css";
import { added } from "./index";
import { observer } from "mobx-react";
function App() {
  console.log("render");
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>{added.addcompute}</p>
        <button onClick={click}>증가</button>
      </header>
    </div>
  );
  function click() {
    added.clicked();
  }
}

export default observer(App);
이제 addcompute뒤에 ()를 지워주세요

이제 보면 화면이 내용이 바뀔때만 render가 된거를 볼수있습니다.

App.js click

import logo from "./logo.svg";
import "./App.css";
import { added } from "./index";
import { observer } from "mobx-react";
function App() {
  console.log("render");
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          {added.add1}
          {added.add2}
        </p>
        <button onClick={click}>증가</button>
      </header>
    </div>
  );
  function click() {
    setTimeout(() => {
      added.clicked();
      added.add2 = 3;
    }, 500);
  }
}

export default observer(App);

이러고 콘솔창을 보면

이렇게 한번눌렀는데 두번 render되는것을 볼수 있습니다 이걸 고치기위해 있는것이 action입니다.

App.js

import logo from "./logo.svg";
import "./App.css";
import { added } from "./index";
import { observer } from "mobx-react";
import { action } from "mobx";
function App() {
  console.log("render");
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          {added.add1}
          {added.add2}
        </p>
        <button onClick={click}>증가</button>
      </header>
    </div>
  );
  function click() {
    setTimeout(
      action(() => {
        added.clicked();
        added.add2 = 3;
      }),
      500
    );
  }
}

export default observer(App);

이렇게 setimeout에 바로 저런식으로 action을 넣어주면  한번만 작동하게 됩니다.

추가로 

 setTimeout(() => {
      runInAction(() => {
        added.clicked();
        added.add2 = 3;
      });
    }, 500);
이렇게 적어도 render가 한번만 작동이 됩니다.

 

그럼 이제 이걸 클래스내부에 넣어서 어떻게 쓰는지 알아보겠습니다.

App.js

import logo from "./logo.svg";
import "./App.css";
import { added } from "./index";
import { observer } from "mobx-react";
import { action, runInAction } from "mobx";
function App() {
  console.log("render");
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          {added.add1}
          {added.add2}
        </p>
        <button onClick={click}>증가</button>
      </header>
    </div>
  );
  function click() {
    setTimeout(() => {
      added.actionadd();
    }, 500);
  }
}

export default observer(App);

index.js

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { action, computed, makeObservable, observable } from "mobx";
class add {
  @observable
  add1 = 1;
  @observable
  add2 = 2;

  constructor() {
    makeObservable(this);
  }
  clicked() {
    this.add1 = this.add1 + 1;
    console.log(this.add1);
  }
  @computed
  get addcompute() {
    if (this.add1 > 10) {
      return 10;
    } else {
      return 0;
    }
  }
  @action
  actionadd() {
    this.add1++;
    this.add2 = 3;
  }
}
export const added = new add();

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

이렇게 하고  콘솔창을 열어보면

이렇게 깔끔하게 두개가 바뀌지만 render는 한번만 되는것을 알수 있습니다.

@action을 빼고 쓰면

이런식으로 render가 두번되고 경고 표시가 나옵니다.

다들 오늘 고생 많으셧습니다.

'React를 같이 배워보자' 카테고리의 다른 글

React27일차-mobx(async)  (0) 2022.02.22
React27일차-mobx(inject,store)  (0) 2022.02.21
React25일차-mobx  (0) 2022.02.19
React24일차-redux-action  (0) 2022.02.13
React24일차-redux-saga  (0) 2022.02.13