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

React27일차-mobx(async)

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

오늘은 기존 프로젝트에서 async를 사용해보겠습니다.

코드열고 npm start해주세요

우선 작동 확인을 위해서 데이터를 한개 더만들어주겟습니다.

context/Database.js 파일 만들어주세요

Database.js

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

export default class Database {
  @observable
  Database = [];

  constructor(roots) {
    makeObservable(this);
  }
  @action
  success(data) {
    this.Database = data;
  }
}
배열을 가지고 있는 database라는 저장공간을 한개 만듭니다

root.js

import { computed, makeObservable, observable } from "mobx";
import add from "./add";
import Database from "./Database";
import sub from "./sub";

export default class root {
  constructor() {
    this.add = new add(this);
    this.sub = new sub(this);
    this.database = new Database(this);
  }
}

이런식으로 root랑 연결시켜 주고

App.js

import logo from "./logo.svg";
import "./App.css";

import { inject, observer } from "mobx-react";
import { useCallback, useEffect } from "react";

function App({ add, sub, database }) {
  console.log(database.Database);
  const datain = useCallback(async () => {
    try {
      const res = await { data: ["hi", "hello", "bye"] };
      database.success(res.data);
    } catch (e) {
      console.alert(e);
    }
  }, [database]);
  useEffect(() => {
    datain();
  }, [datain]);
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          {add.add1}
          {add.add2}
          {sub.sub1}
          {sub.sub2}
          {database.Database}
        </p>
        <button onClick={click}>증가</button>
      </header>
    </div>
  );
  function click() {
    setTimeout(() => {
      add.actionadd();
    }, 500);
  }
}

export default inject("add", "sub", "database")(observer(App));

이런식으로 밑에 database 적어서 데이터쓸수잇게하고 인자로 database받아서 사용할수 있게 합니다.

const datain = useCallback(async () => {
    try {
      const res = await { data: ["hi", "hello", "bye"] };
      database.success(res.data);
    } catch (e) {
      console.alert(e);
    }
  }, [database]);
이렇게 만들어서 async로 데이터를 가져오게 됩니다.  그리고 아까 정의한 success함수로 그데이터를 Database에 저장합니다.
 useEffect(() => {
    datain();
  }, [datain]);

여기서 만든 함수를 실행시켜주고 

  <p>
          {add.add1}
          {add.add2}
          {sub.sub1}
          {sub.sub2}
          {database.Database}
     </p>
 여기서 저장된 데이터가 출력되게 됩니다.
npm start해서 확인해보면

이렇게 제대로 나오는것을 확인할수있습니다. 그럼이번에는 이걸 클래스 Database클래스 내부에서 정의해보겠습니다.

Databse.js 

import { DOM_KEY_LOCATION } from "@testing-library/user-event/dist/keyboard/types";
import { action, computed, flow, makeObservable, observable } from "mobx";

export default class Database {
  @observable
  Database = [];

  constructor(roots) {
    makeObservable(this);
  }
  @action
  success(data) {
    this.Database = data;
  }

  async datain() {
    try {
      const res = await { data: ["hi", "hello", "bye"] };
      this.success(res.data);
    } catch (e) {
      console.alert(e);
    }
  }

  @flow
  *datainflow() {
    try {
      const res = yield { data: ["hi", "hello", "bye"] };
      this.success(res.data);
    } catch (e) {
      console.alert(e);
    }
  }
}

  async datain() {
    try {
      const res = await { data: ["hi", "hello", "bye"] };
      this.success(res.data);
    } catch (e) {
      console.alert(e);
    }
  }

이런식으로 async를 붙여서 작성해도 작동이 가능하고 

@flow
  *datainflow() {
    try {
      const res = yield { data: ["hi", "hello", "bye"] };
      this.success(res.data);
    } catch (e) {
      console.alert(e);
    }
  }
이렇게 @flow쓰고 젤앞에 *넣어주면 async를 안적고 await대신 yield를 넣고 해도 제대로 동작이 된다.
 
App.js
import logo from "./logo.svg";
import "./App.css";

import { inject, observer } from "mobx-react";
import { useCallback, useEffect } from "react";

function App({ add, sub, database }) {
  console.log(database.Database);

  useEffect(() => {
    database.datainflow();
  }, [database]);
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          {add.add1}
          {add.add2}
          {sub.sub1}
          {sub.sub2}
          {database.Database}
        </p>
        <button onClick={click}>증가</button>
      </header>
    </div>
  );
  function click() {
    setTimeout(() => {
      add.actionadd();
    }, 500);
  }
}

export default inject("add", "sub", "database")(observer(App));

앞에 database.만 붙여주면 자동으로 적용이된다. 

npm star가서 확인해보면

이렇게 정상적으로 작동이 되고있다.

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

React는 여기까지하고 나중에 제가 혼자페이지 만들어보고 그거 설명하는걸로 나중에 찾아오겠습니다.