[React] 외부 API 호출에 대한 상태 관리

강버섯·2022년 1월 27일
0

React Overview

목록 보기
3/8

👉 상태 관리 방법

👉 call back

axios.get('https://example.com', function(res, err) {
  if (err) {
    console.error(err.message);
  }
  
  if (res) {
    console.log(res.data);
    return res.data;
  }
};

함수의 비동기적인 처리를 하기위해서 callback을 사용한다.
비동기로 함수를 동작하게 되면, 언제 끝나는지에 대해 알지 못하기 때문에 완료 후 실행할 함수를 같이 던져준다.

👉 promise

axios.get('http://example.com')
.then( // promise를 통해 resolve된 값을 받아옴
  (res) => {
    console.log(res.data)
    return res.data
  }
)
.catch( //error 발생 시 처리
  (err) => {
    console.log(err.message)
  }
)

callback을 사용할 경우 중첩적인 callback으로 인한 문제가 발생할 수 있는데, 그런 코드가 생성되지 않게하기 위해서 사용하는 것이 promise이다.
axios.get('http://example.com')만을 실행하면 아무 일도 일어나지 않기 때문에 .then()을 붙여줘야 promise가 실행된다.
에러가 발생했을 때의 처리는 .catch()를 통해 할 수 있다.

then은 바로 붙여주지 않아도 promise를 실행시킬 때 붙여 사용하는 것이 가능하다.

function myAsyncJob(){
return new Promise()
}

myAsyncJob.then(~)

👉 async / await

promise를 더 쉽게 사용할 수 있도록 해주는 구문이다.
async / await를 사용하면 promise를 절차적 프로그래밍 방식으로 표현할 수 있다.

await는 항상 async 함수 내에서만 사용이 가능하다.

const job = async () => {
	try {
	  const res = await axios.get('http://example.com')
	  console.log(res.data)
	} catch(err) {
	  console.error(err.message)
	}
}
job()

api의 call이 성공적으로 실행이 되면 res가 데이터를 받게된다.
에러에 대한 처리를 하고 싶다면 try / catch 구문을 사용해서 처리를 진행하면 된다.

const job = async () => {
	try {
		const res = await myAsyncJob() 
		console.log(0)
		console.log(res)
	} catch(err) {
	  console.log(err.message)
	}
}

job()

async / await 구문은 promise를 받아서 처리하는 구문이기 때문에 생성된 promise(위의 코드에서는 myAsyncJob())을 추후에 async / await를 이용해 실행시키는 것이 가능하다.

👉 React Query

React Query는 React app에서 비동기를 쉽게 다룰 수 있게 해주는 라이브러리이다.
React에서 외부 api의 call과 그에 대한 상태관리는 주로 axios와 React Query를 같이 사용하는 방식으로 처리한다고 한다.

👉 사용하기 전에

React Query 사용을 위해 설치를 진행해준다.

$> yarn add react-query

React Query는 가장 상단의 파일에서(react.js는 App.js, Next.js는 _app.js)에서

  1. QueryClient를 선언하고, 선언한 query client를 <QueryclientProvider>의 client를 넘겨준 뒤
  2. <QueryClientProvider>로 컴포넌트들을 감싸줘야만

사용할 수 있다.

_app.js 👇

import { QueryClient, QueryClientProvider } from 'react-query'
import {ReactQueryDevtools} from "react-query/devtools"
import '../styles/globals.css'

const queryClient = new QueryClient();

function MyApp({ Component, pageProps }) {
  return (<QueryClientProvider client={queryClient}>
    <Component {...pageProps} />
  </QueryClientProvider>);
}

export default MyApp;

React Query에서는 Devtool을 지원해주는데, 사용하기 위해서는 <QueryClientProvier> 하위에 작성해주면 된다.

import { QueryClient, QueryClientProvider } from 'react-query'
import {ReactQueryDevtools} from "react-query/devtools"
import '../styles/globals.css'

const queryClient = new QueryClient();

function MyApp({ Component, pageProps }) {
  return (<QueryClientProvider client={queryClient}>
    <Component {...pageProps} />
    <ReactQueryDevtools initialIsOpen={false}/>
  </QueryClientProvider>);
}

export default MyApp;

실행시키면 다음과 같은 Devtool 창을 확인할 수 있다.

👉 시작하기

React Query는 useQuery라는 hook을 사용해서 쓸 수 있다.
useQuery hook의 첫번째 param은 값이 저장되는 변수(혹은 리스트), 두번째 param은 promise를 return하는 함수이다.

import axios from "axios";
import Link from "next/link";
import { useQuery } from "react-query";

const TodoPage = () => {
    const getTodos = async () => {
        const resp = await axios.get("/api/todos")
        return resp.data
    }


	const query = useQuery("todos", getTodos)

    return <pre>{JSON.stringify(query, null, 2)}</pre>


useQuery를 통해 받아온 값을 확인해보면

  • status
  • isLoading : 요청 loading 중일 때 true
  • isSusscess : 요청 성공 시 true
  • isError : 요청 수행 중 error 발생할 시 true
  • isIdel : query data가 하나도 없고 비었을 때 {enabled : false} 상태이며, 이 값이 기본값(query가 호출되었을 때의 값) 이다.
  • data : 요청해서 받은 data

값이 담겨 있는 것을 확인할 수 있다.

profile
무럭무럭 버섯농장

0개의 댓글