본문 바로가기
카테고리 없음

리액트 async와 await (feat. rest-API, graphql-API)

by 제이엠_ 2022. 1. 13.

동기와 비동기

리액트에서 async와 await를 알아보기 전에 동기와 비동기에 대해 알아봐야 한다. 동기는 API를 요청 응답하는데 있어서 하나의 응답이 끝난 이후에 요청이 들어가는 방식이다.

출처 : (주)뉴비즈스타트 코드캠프

 

비동기는 동기와 달리 여러 일을 할 때 사용한다. 예를 들어 네이버의 경우 뉴스의 게시글 목록을 가져오는 동시에 상품 목록을 가져오는 경우에 해당한다. 스마트폰에서 게임을 다운로드하면서 카톡 하는 나의 모습이 비동기의 모습과 같다. 

 

출처 : (주)뉴비즈스타트 코드캠프

 

async와 await

rest-API나 graphql-API 를 사용해서 요청에 대한 응답으로 받은 객체(JSON)를 변수에 담아서 사용하는데 응답 결과를 변수에 담아서 사용하려면 통신이 완료될 때까지 기다려야 한다. 그때 사용하는 것이 asyncawait이다.

 

// mutation에 동기식 처리
async function handleClickPost(){

		const result = await createBoard({
									variables: {
									aaa: "훈이",
									bbb: "1234",
									ccc: "안녕하세요 훈이에요",
									ddd: "반갑습니다"
								}
							})

		// 결과물 확인하기
		console.log(result)

}

return (
	<button onClick={handleClickPost}>게시물 등록</button>
)

버튼을 눌렀을 때 onClick={hanleClickPost}에 의해 handleClickPost 함수가 실행되며 async와 await로 통신을 연결시켜준다.

 

동기 통신과 비동기 통신은 await의 유무에 따라 달라진다.

// 비동기 통신
async function 함수명() {
	axios('API이름')// 서버에 요청하는 코드 (기다리지 않음)
}


// 동기 통신
async function 함수명() {
	await axios('API이름') // 서버에 요청하는 코드 (기다림)
}
--------------------------------------------------------------------------------
// 화살표 함수의 경우
const 함수명 = async () => {
	await // 서버에 요청하는 코드
}

 

동기와 비동기 방식에서 결과값은 달라진다. 비동기 통신의 경우는 Promise라는 값을 볼 수 있게 되고 동기 통신의 경우 우리가 원하는 객체(JSON)의 형식으로 볼 수 있게 된다.

// 비동기 통신
async function 함수이름(){
	const data = axios.get('https://koreanjson.com/posts/1')
	console.log(data)     // Promise


// 동기 통신
async function 함수이름(){
	const data = await axios.get('https://koreanjson.com/posts/1')
	console.log(data)     // {id:1, title:"정당의 목적이나 활동이...", ...}
}

 

실습사례

VSCODE에서 rest-API를 이용하여 JSON 데이터를 요청한다면 axios를 이용해야 하는데, axios를 다운로드한 뒤에 import를 진행하면 된다. rest-API의 사례를 살펴보면 아래와 같다.

import axios from "axios";
import { useState } from "react";

export default function restGet() {
  const [aaa, setAaa] = useState("");

  //   async function zzz() {
  //     const result = await axios.get("https://koreanjson.com/posts/1");
  //     console.log(result.data.title);
  //     setAaa(result.data.title);
  //   }
  // 화살표 함수
  const zzz = async () => {
    const result = await axios.get("https://koreanjson.com/posts/1");
    console.log(result.data.title);
    setAaa(result.data.title);
  };

  //   function zzz() {
  //     console.log("어쩔티비");
  //   }

  return (
    <>
      <button onClick={zzz}>Rest-API 요청하기!!!</button>
      <div>{aaa}</div>
    </>
  );
}

//zzz는 이벤트핸들러 함수
//함수가 중복되면 에러발생할 수 있음. 막으려면 함수를 const로

state를 활용하여 버튼을 클릭했을 때 https://koreanjson.com/posts/1 API에 요청하여 해당 제목을 가져오게 된다.

 

주로 사용하게 될 graphql-API는 이와 다른데 먼저 _app.js에 import를 해줘야한다.

import "../styles/globals.css";
import { ApolloClient, InMemoryCache, ApolloProvider } from "@apollo/client";

function MyApp({ Component, pageProps }) {
  const client = new ApolloClient({
    uri: "api주소",
    cache: new InMemoryCache(),
  });

  return (
    <ApolloProvider client={client}>
      <Component {...pageProps} />
    </ApolloProvider>
  );
}

export default MyApp;

 

그리고 index.js를 살펴보면 apollo/client를 통해서 useMutation, gql을 활용한다.

import { useMutation, gql } from "@apollo/client";
import { useState } from "react";

const CREATE_BOARD = gql`
  mutation {
    createBoard(
      writer: "철수"
      title: "제목입니다~"
      contents: "내요이에요~~"
    ) {
      _id
      number
      message
    }
  }
`;

export default function GraphqlMutation() {
  const [aaa, setAaa] = useState("");
  const [qqq] = useMutation(CREATE_BOARD);

  const zzz = async () => {
    // const result = await axios.get("https://koreanjson.com/posts/1");
    const result = await qqq();
    // console.log(result.data.title);
    // setAaa(result.data.title);
    console.log(result.data.createBoard.message);
    setAaa(result.data.createBoard.message);
  };

  return (
    <>
      <button onClick={zzz}>Graphql-API 요청하기!!!</button>
      <div>{aaa}</div>
    </>
  );
}

//zzz는 이벤트핸들러 함수
//함수가 중복되면 에러발생할 수 있음. 막으려면 함수를 const로

조회가 아닌 데이터를 생산/수정하는 것으로 query가 아닌 mutation으로 useMutation을  apollo/client에서 가져온다.

 

댓글