이번에는 리액트에서 API 콜을 하는 2가지 방법에 대해서 알아보겠습니다. 사실, 리액트도 자바스크립트 문법을 활용하기 때문에, 순수 바닐라 자바스크립트를 이용해서 어플리케이션을 만들어보셨다면, fetch
API와 AXIOS
API에 대해서 잘 알고 있을 겁니다. 리액트에서는 어떻게 이 API 호출 메서드를 사용할 수 있는지 알아보겠습니다.
useEffect Hook을 활용하여, 컴포넌트가 최초 렌더링 후 mount될 때 한 번만 데이터를 동적으로 받아올 수 있도록 할 수 있습니다. 이 때, fetch 또는 axios를 이요해서 데이터를 받아옵니다.
서버 구축을 통한 데이터를 받아오기 어려운 상황에서, 다음의 사이트에서 fake API를 활용해 화면에 뿌려볼 수 있습니다. https://jsonplaceholder.typicode.com/
import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
function News(){
const [data, setData] = useState([]);
useEffect(() => {
const fetchData = async() => {
const res = await fetch('https://jsonplaceholder.typicode.com/news');
const result = res.json();
return result;
}
fetchData().then(res => setData(res));
}, []);
return (
<div>
{data.map(d => (
<Link key={d.id} to={`${d.id}`}>{d.title}</Link>
))}
</div>
)
}
fetch API는 별도의 설치 없이, 자바스크립트를 사용한다면 내장되어 있기 때문에, 자바스크립트의 다른 메서드처럼 사용하면 됩니다. 그리고, fetch 메서드를 활용해서 data를 가져오면, 해당 응답은 json 객체로 변환 후 return 하여야 합니다
asycn-await 구문에서 await가 담겨 있는 코드의 줄은 데이터를 비동기적으로 가져올 때까지 기다리고, async 키워드가 붙여진 함수의 외부에 위치한 코드는 먼저 동작합니다. 또, await 구문은 기다렸다가 데이터를 받아오면, 절차적으로 async 함수 내부의 코드를 순서대로 실행합니다. Promise then 체이닝을 통해 길어지는 코드보다, 더 명시적으로 코드의 관계를 확인할 수 있다는 점에서
async-await
사용이 권장되어 집니다.
axios는 fetch API와 유사한 Promise 기반 HTTP 클라이언트 라이브러리로 데이터를 동적으로 받아올 수 있습니다. fetch API와 달리 third-party 라이브러리로 1) 별도의 설치 후 import 하거나 또는 2) html 파일에 jsDeliver CDN을 이용해 사용 가능합니다.
-----------------
npm install axios
-----------------
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { Link } from 'react-router-dom';
function News(){
const [data, setData] = useState([]);
useEffect(() => {
const fetchData = async() => {
const res = await axios.get('https://jsonplaceholder.typicode.com/news');
return res.data;
}
fetchData().then(res => setData(res));
}, []);
return (
<div>
{data.map(d => (
<Link key={d.id} to={`${d.id}`}>{d.title}</Link>
))}
</div>
)
}
axios는 fetch API와 달리 json 객체로 변환해주는 과정을 자동으로 해줍니다. 그리고 위의 코드에서 axios.get
메서드를 활용해 데이터를 비동기적으로 받아올 수 있습니다. 단, 응답 받은 객체에 data key에 접근하여 접근한 값(res.data
)을 반환해야 데이터를 활용 가능합니다.
지금과 같은 상황에서 이런 의문이 들 수도 있습니다.
useEffect의 첫 번째 인자인 콜백함수 자체에 async-await
를 활용하면 어떨까요?
useEffect 부분의 코드만 바꾸고 결과를 확인해보겠습니다.
useEffect(async () => {
const res = await axios.get('https://jsonplaceholder.typicode.com/news/1');
setData(res.data);
}, []);
실행하면 eslint를 통해 다음과 같은 오류의 결과를 확인할 수 있습니다.
useEffect의 콜백함수는 'race condition'을 막기 위해 동기적이다. 따라서, async 함수를 콜백함수의 내부에 넣으라고 알려줍니다.
위에서 다룬 예제들은 빈 의존성 배열 상태이므로, 최초 컴포넌트 렌더링 후 마운트 된 직후 데이터를 비동기적으로 받아온 예제를 보여주었습니다. 위와 같은 단적인 상황뿐만 아니라, 로그인, 회원가입과 같은 상황에서 첫 렌더링 이후의 과정에서도 데이터를 비동기적으로 받아와야 하는 상황이 발생할 수 있습니다. 단계적으로 이후에 한 번 더 복잡한 상황에 대해서도 알아볼 예정이며, 다음에는 swr 또는 이전에 다루고자 했던 useRef hook을 활용한 비제어 컴포넌트에 대해서 알아보는 시간을 가져보겠습니다.