FRONT-END/REACTJS

react 비동기 작업

JINGMONG 2022. 2. 19. 22:19

웹을 만들다보면 처리할 때 시간이 걸리는 작업이 있다. 웹에서 서버 쪽 데이터가 필요할 때는 Ajax 기법을 사용하셔 서버의 API를 호출함으로써 데이터를 수신한다. 이렇게 서버 API를 사용해야 할 때는 네트워크 송수신 과정에서 시간이 걸리기 때문에 즉시 처리되는 것이 아니라, 응답을 받을 때까지 기다렸다가 전달받은 응답 데이터를 처리한다.

자바스크립트에서 비동기 작업을 할 때 흔히 사용하는 방법은 콜백 함수를 사용하는 것이다.

콜백 함수

function increase(number, callback) {
  setTimeout(() => {
    const result = number + 10;
    if (callback) {
      callback(result);
    }
  }, 1000)
}

increase(0, result => {
  console.log(result);
});

Promise

Promise는 콜백 지옥 같읒 코드가 형성되지 않게 하는 방안이다.

function increase(number) {
  const promise = new Promise((resolve, reject) => {
    setTimeout(() => {
      const result = number + 10;
      if (result > 50) {
        const e = new Error('NumberTooBig);
        return reject(e);
      }
      resolve(result);
    }, 1000);
  });
  return promise;
}

increse(0)
  .then(number => {
    console.log(number);
    return increase(number);
  })
  .then(number => {
    console.log(number);
    return increase(number);
  })
  .then(number => {
    console.log(number);
    return increase(number);
  })
  .then(number => {
    console.log(number);
    return increase(number);
  })
  .then(number => {
    console.log(number);
    return increase(number);
  })
  .catch(e => {
    console.log(e);
  });

여러 작업을 연달아 처리한다고 해서 함수를 여러번 감싸는 것이 아니라, .then을 사용하여 그다음 작업을 설정하기 때문에 콜백 지옥이 형성되지 않는다.

async/await

async/await는 Promise를 더욱 쉽게 사용할 수 있도록 해주는 문법이다. 이 문법을 사용하려면 함 앞부분에 async 키워드를 추가하고, 해당 함수 내부에서 Promise의 앞부분에 await 키워드를 사요한다. 이렇게 하면 Promise가 끝날 때까지 기다리고, 결과 값을 특정 변수에 담을 수 있다.

function increase(number) {
  const promise = new Promise((resolve, reject) => {
    setTimeout(() => {
      const result = number + 10;
      if (result > 50) {
        const e = new Error('NumberTooBig);
        return reject(e);
      }
      resolve(result);
    }, 1000);
  });
  return promise;
}

async function runTask() {
  try {
    let result = await increase(0);
    console.log(result);
    result = await increase(0);
    console.log(result);
    result = await increase(0);
    console.log(result);
    result = await increase(0);
    console.log(result);
    result = await increase(0);
    console.log(result);
    result = await increase(0);
    console.log(result);
  } catch(e) {
    console.log(e);
  }
}

axios로 API 호출해서 데이터 받기

axios는 현재 가장 많이 사용되고 있는 자바스크립트 HTTP 클라이언트 이다. 이 라이브러리의 특징은 HTTP 요청을 Promise 기반으로 처리한다는 점이다.

import React, { useState } from "react";
import axios from "../node_modules/axios/index";

const App = () => {
  const [data, setData] = useState(null);
  const onClick = () => {
    axios
      .get("<https://jsonplaceholder.typicode.com/todos/1>")
      .then((response) => {
        setData(response.data);
      });
  };
  return (
        <div>
      <div>
        <button onClick={onClick}>불러오기</button>
      </div>
      {data && (
        <textarea rows={7} value={JSON.stringify(data, null, 2)} readOnly />
      )}
    </div>
  );
};

export default App;
import React, { useState } from "react";
import axios from "../node_modules/axios/index";

const App = () => {
  const [data, setData] = useState(null);
  const onClick = async () => {
    try {
      const response = await axios.get(
        "<https://jsonplaceholder.typicode.com/todos/1>"
      );
      setData(response.data);
    } catch (e) {
      console.log(e);
    }
  };
  return (
    <div>
      <div>
        <button onClick={onClick}>불러오기</button>
      </div>
      {data && (
        <textarea rows={7} value={JSON.stringify(data, null, 2)} readOnly />
      )}
    </div>
  );
};

export default App;

데이터 연동

컴포넌트가 화면에 보이는 시점에 API를 요청. useEffect를 사용하여 컴포넌트가 처음 렌더링 되는 시점에 API를 요청 useEffect에 등록하는 함수에 async를 붙이면 안된다. useEffect에서 반환해야 하는 값은 뒤정리 함수이기 때문. useEffect 내부에서 async/await를 사용하고 싶다면 함수 내부에 async 키워드가 붙은 또다른 함수를 만들어서 사용해야 한다.

'FRONT-END > REACTJS' 카테고리의 다른 글

리덕스 라이브러리  (0) 2022.02.19
Context API  (0) 2022.02.19
react route로 SPA 개발  (0) 2022.02.19
컴포넌트 스타일링  (0) 2022.02.19
Hooks  (0) 2022.01.03