REACT Axios, fetch API, SWR, React Query ์๋ฒ ํต์ ๋ฐ ๋ฐ์ดํฐ ํ์นญ ์ต์ ํ ์ปดํฌ๋ํธ
ํ๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ค์ํ ๋ฐ์ดํฐ๋ฅผ ์๋ฒ์ ์ฃผ๊ณ ๋ฐ์ผ๋ฉฐ ๋์ํฉ๋๋ค. ๋ฐ๋ผ์, ํจ์จ์ ์ด๊ณ ์์ ์ ์ธ ๋ฐ์ดํฐ ํ์นญ์ ์ฌ์ฉ์ ๊ฒฝํ๊ณผ ์ ํ๋ฆฌ์ผ์ด์ ์ฑ๋ฅ์ ์ง์ ์ ์ธ ์ํฅ์ ๋ฏธ์นฉ๋๋ค.
์ด๋ฒ ํฌ์คํ ์์๋ REACT axios, fetch API, SWR, React Query ๋ฑ ๋ค์ํ ๋๊ตฌ๋ฅผ ํ์ฉํ์ฌ ์๋ฒ์์ ํต์ ์ ์ต์ ํํ๊ณ , ๋ฐ์ดํฐ ํ์นญ์ ํจ๊ณผ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์๋ ์ปดํฌ๋ํธ ๋์์ธ ์ ๋ต์ ๋ํด ์์ธํ ์์๋ณด๊ฒ ์ต๋๋ค.
REACT ์๋ฒ ํต์ ๋ฐ ๋ฐ์ดํฐ ํ์นญ์ ์ค์์ฑ
๋ฐ์ดํฐ ํ์นญ ์ต์ ํ๋ ์ฌ๋ฌ ์ธก๋ฉด์์ ์ค์ํฉ๋๋ค.
- ๋น ๋ฅธ ์๋ต ์๋: ์๋ฒ์์ ํต์ ์ง์ฐ ์๊ฐ์ ์ต์ํํ์ฌ, ์ฌ์ฉ์์๊ฒ ๋น ๋ฅธ ํผ๋๋ฐฑ์ ์ ๊ณตํฉ๋๋ค.
- ๋คํธ์ํฌ ๋น์ฉ ์ ๊ฐ: ํ์ํ ๋ฐ์ดํฐ๋ง ํจ์จ์ ์ผ๋ก ๊ฐ์ ธ์ ๋ถํ์ํ ๋คํธ์ํฌ ์์ฒญ์ ์ค์ ๋๋ค.
- ๋ฐ์ดํฐ ์ผ๊ด์ฑ ์ ์ง: ์ต์ ๋ฐ์ดํฐ ์ํ๋ฅผ ๋ฐ์ํ๊ณ , ์บ์ฑ์ ํตํด ์ค๋ณต ์์ฒญ์ ๋ฐฉ์งํ์ฌ ๋ฐ์ดํฐ ์ผ๊ด์ฑ์ ๋์ ๋๋ค.
- ์ฌ์ฉ์ ๊ฒฝํ ๊ฐ์ : ๋ก๋ฉ ์ํ ๊ด๋ฆฌ, ์๋ฌ ์ฒ๋ฆฌ ๋ฑ์ ํตํด ์ฌ์ฉ์๊ฐ ์ํํ๊ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ด์ฉํ ์ ์๋๋ก ๋์ต๋๋ค.
์ฃผ์ ๋๊ตฌ ๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์๊ฐ
Axios์ Fetch API
๋ ๋๊ตฌ๋ ๋ชจ๋ ์๋ฒ์์ HTTP ํต์ ์ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค.
- Axios: Promise ๊ธฐ๋ฐ์ HTTP ํด๋ผ์ด์ธํธ๋ก, ์์ฒญ ๋ฐ ์๋ต ์ธํฐ์
ํฐ, ์๋ JSON ๋ณํ, ์์ฒญ ์ทจ์ ๋ฑ ๋ค์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
- ์ฅ์ : ์ง๊ด์ ์ธ API, ์๋ฌ ์ฒ๋ฆฌ ๋ฐ ์ธํฐ์ ํฐ ๊ธฐ๋ฅ, ๋ธ๋ผ์ฐ์ ์ Node.js ํ๊ฒฝ ๋ชจ๋ ์ง์
- ๋จ์ : ์ถ๊ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น ํ์
- Fetch API: ๋ด์ฅ ๋ธ๋ผ์ฐ์ API๋ก, Promise ๊ธฐ๋ฐ์ ์์ฒญ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ฉฐ ๋ณ๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ด ๋ฐ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
- ์ฅ์ : ๋ธ๋ผ์ฐ์ ์ ๊ธฐ๋ณธ ํฌํจ๋์ด ์์ด ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ถํ์
- ๋จ์ : ์๋ฌ ์ฒ๋ฆฌ ๋ฐ ์๋ต ํ์ฑ์ ์ถ๊ฐ ์ฝ๋๊ฐ ํ์, ์ผ๋ถ ์ค๋๋ ๋ธ๋ผ์ฐ์ ์์๋ ํด๋ฆฌํ ํ์
SWR๊ณผ React Query
๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ฐ์ดํฐ ํ์นญ์ ๋ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ๊ธฐ ์ํด ๋ง๋ค์ด์ก์ผ๋ฉฐ, ๊ฐ๊ฐ์ ๊ฐ์ ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
- SWR (stale-while-revalidate): Vercel์์ ๋ง๋ ๊ฒฝ๋ ๋ฐ์ดํฐ ํ์นญ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก, ์บ์ฑ, ์๋ ์ฌ๊ฒ์ฆ, ํฌ์ปค์ค ๋ฆฌํ์นญ ๋ฑ ๋ค์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ฌ ์ต์ ๋ฐ์ดํฐ๋ฅผ ์ ์งํ๋ฉด์๋ ๋น ๋ฅธ ์๋ต ์๋๋ฅผ ๋ณด์ฅํฉ๋๋ค.
- ์ฃผ์ ๊ธฐ๋ฅ:
- ์บ์์ ์ฌ๊ฒ์ฆ ์ ๋ต:
- stale-while-revalidate
- ์๋ ๋ฐ์ดํฐ ๊ฐฑ์
- ๊ฐ๊ฒฐํ API ์ค๊ณ
- ์ฃผ์ ๊ธฐ๋ฅ:
- React Query: ๋ฐ์ดํฐ ํ์นญ, ์บ์ฑ, ์
๋ฐ์ดํธ ๋ฐ ๋๊ธฐํ ๊ธฐ๋ฅ์ ๋งค์ฐ ๊ฐ๋ ฅํ๊ฒ ์ง์ํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก, ๋ณต์กํ ๋ฐ์ดํฐ ์ํ ๊ด๋ฆฌ์ ์๋ฒ ์ํ ๋๊ธฐํ๋ฅผ ์ฝ๊ฒ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
- ์ฃผ์ ๊ธฐ๋ฅ:
- ์บ์ฑ, ๋ฐฑ๊ทธ๋ผ์ด๋ ์ ๋ฐ์ดํธ
- ์ฟผ๋ฆฌ ๋ฌดํจํ์ ์ฌ์์ฒญ ๊ด๋ฆฌ
- ์ ์ญ ์ํ์ ๋ก์ปฌ ์ํ์ ๋ถ๋ฆฌ
- ์ฃผ์ ๊ธฐ๋ฅ:
์ปดํฌ๋ํธ ์ค๊ณ ์ ๋ต
1. API ์์ฒญ ๋ฐ ์๋ต ๊ด๋ฆฌ
API ์์ฒญ ์ ๊ณตํต์ ์ธ ์๋ฌ ์ฒ๋ฆฌ, ๋ก๋ฉ ์ํ ๊ด๋ฆฌ, ๋ฐ์ดํฐ ๋ณํ ๋ฑ์ ์ํ ๋ํผ(wrapper)๋ฅผ ์ค๊ณํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์๋ฅผ ๋ค์ด, Axios๋ฅผ ์ฌ์ฉํ์ฌ ์์ฒญ ์ธํฐ์ ํฐ์ ์๋ต ์ธํฐ์ ํฐ๋ฅผ ์ค์ ํ๋ฉด, ๋ชจ๋ ์์ฒญ์ ๋ํด ์ผ๊ด๋ ์๋ฌ ์ฒ๋ฆฌ์ ์ธ์ฆ ํ ํฐ ๊ฐฑ์ ๋ก์ง์ ์ค์์์ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
// apiClient.js
import axios from 'axios';
const apiClient = axios.create({
baseURL: 'https://api.example.com',
timeout: 5000,
});
// ์์ฒญ ์ธํฐ์
ํฐ
apiClient.interceptors.request.use(
config => {
// ์: ์ธ์ฆ ํ ํฐ ์ถ๊ฐ
const token = localStorage.getItem('authToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
error => Promise.reject(error)
);
// ์๋ต ์ธํฐ์
ํฐ
apiClient.interceptors.response.use(
response => response,
error => {
// ์๋ฌ ๋ก๊น
๋ฐ ์ฒ๋ฆฌ
console.error('API Error:', error);
return Promise.reject(error);
}
);
export default apiClient;
์ด์ ๊ฐ์ด ๊ณตํต ๋ก์ง์ ๋ถ๋ฆฌํ๋ฉด, ๊ฐ ์ปดํฌ๋ํธ์์๋ ๋ฐ์ดํฐ ํ์นญ ๋ก์ง์ ์ง์คํ ์ ์์ด ์ฝ๋์ ๊ฐ๋ ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ด ํฅ์๋ฉ๋๋ค.
2. ์บ์ฑ๊ณผ ์ฌ๊ฒ์ฆ ์ ๋ต
SWR๊ณผ React Query๋ ์บ์ฑ ๋ฐ ์๋ ์ฌ๊ฒ์ฆ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ฌ, ์ฌ์ฉ์ ์ธํฐ๋์ ์ ๋ฐ๋ผ ์ต์ ๋ฐ์ดํฐ๋ฅผ ์ ์งํ๋ฉด์๋ ๋ถํ์ํ ๋คํธ์ํฌ ์์ฒญ์ ์ค์ ๋๋ค.
SWR ์ฌ์ฉ ์์
// UserProfile.jsx
import React from 'react';
import useSWR from 'swr';
import apiClient from './apiClient';
const fetcher = url => apiClient.get(url).then(res => res.data);
const UserProfile = () => {
const { data, error } = useSWR('/user/profile', fetcher, {
refreshInterval: 30000, // 30์ด๋ง๋ค ์๋ ๊ฐฑ์
});
if (error) return <div>์๋ฌ ๋ฐ์: {error.message}</div>;
if (!data) return <div>๋ก๋ฉ ์ค...</div>;
return (
<div>
<h2>{data.name}๋์ ํ๋กํ</h2>
<p>์ด๋ฉ์ผ: {data.email}</p>
</div>
);
};
export default UserProfile;
์ ์์ ๋ SWR์ ์ฌ์ฉํ์ฌ /user/profile API๋ฅผ ํธ์ถํ๊ณ , 30์ด๋ง๋ค ๋ฐ์ดํฐ๋ฅผ ์๋ ๊ฐฑ์ ํฉ๋๋ค. SWR์ ์บ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฆ์ ๋ฐํํ ํ, ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์ต์ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ์ฌ UI๋ฅผ ์ต์ ์ํ๋ก ์ ์งํฉ๋๋ค.
React Query ์ฌ์ฉ ์์
// OrderList.jsx
import React from 'react';
import { useQuery } from 'react-query';
import apiClient from './apiClient';
const fetchOrders = async () => {
const { data } = await apiClient.get('/orders');
return data;
};
const OrderList = () => {
const { data, error, isLoading } = useQuery('orders', fetchOrders, {
refetchOnWindowFocus: true, // ์ฐฝ ํฌ์ปค์ค ์ ๋ฐ์ดํฐ ์ฌ์์ฒญ
});
if (isLoading) return <div>๋ก๋ฉ ์ค...</div>;
if (error) return <div>์๋ฌ ๋ฐ์: {error.message}</div>;
return (
<div>
<h2>์ฃผ๋ฌธ ๋ชฉ๋ก</h2>
<ul>
{data.map(order => (
<li key={order.id}>
์ฃผ๋ฌธ ๋ฒํธ: {order.id}, ๊ธ์ก: {order.amount}์
</li>
))}
</ul>
</div>
);
};
export default OrderList;
React Query๋ 'orders'๋ผ๋ ์ฟผ๋ฆฌ ํค๋ก ๋ฐ์ดํฐ๋ฅผ ์บ์ฑํ๊ณ , ์ฐฝ ํฌ์ปค์ค ์ ๋ฐ์ดํฐ๋ฅผ ์๋ ์ฌ์์ฒญํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ฅผ ํตํด ์ฌ์ฉ์๊ฐ ์ธ์ ๋ ์ต์ ๋ฐ์ดํฐ๋ฅผ ํ์ธํ ์ ์๋๋ก ์ง์ํฉ๋๋ค.
3. ์ ์ญ ์ํ์ ๋ก์ปฌ ์ํ์ ๋ถ๋ฆฌ
์๋ฒ์์ ๋ฐ์์จ ๋ฐ์ดํฐ๋ ์ผ๋ฐ์ ์ผ๋ก ์ ์ญ ์ํ๋ก ๊ด๋ฆฌํ๊ธฐ๋ณด๋ค๋, ๊ฐ ์ปดํฌ๋ํธ ๋ด๋ถ์์ ๋ก์ปฌ ์ํ๋ก ๊ด๋ฆฌํ๋ ๊ฒ์ด ์ข์ต๋๋ค. React Query์ SWR์ ์๋ฒ ์ํ๋ฅผ ๋ณ๋์ ์บ์ ์คํ ์ด๋ก ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์, ์ ์ญ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(Redux, MobX ๋ฑ)์ ๋ถ๋ฆฌํ์ฌ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด, ํด๋ผ์ด์ธํธ์ UI ์ํ์ ์๋ฒ์์ ๊ฐ์ ธ์จ ๋ฐ์ดํฐ ์ํ๊ฐ ๋ ๋ฆฝ์ ์ผ๋ก ๊ด๋ฆฌ๋์ด ์ ์ง๋ณด์๊ฐ ์ฌ์์ง๋๋ค.
4. ๋ฐ์ดํฐ ํ์นญ ์ต์ ํ๋ฅผ ์ํ ์ฝ๋ ์คํ๋ฆฌํ
๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์ ์์๋ ๊ฐ ํ์ด์ง๋ณ๋ก ํ์ํ API ํธ์ถ์ ๋ถ๋ฆฌํ๊ณ , ์ฝ๋ ์คํ๋ฆฌํ ์ ํตํด ์ด๊ธฐ ๋ก๋ฉ ์ ๋ถํ์ํ ๋ฐ์ดํฐ ์์ฒญ์ ์ต์ํํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. Next.js์ ๊ฐ์ ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ๋ฉด, ํ์ด์ง๋ณ๋ก ๋ฐ์ดํฐ ํ์นญ ํจ์๋ฅผ ๋ถ๋ฆฌํ์ฌ ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง(SSR)์ด๋ ์ ์ ์ฌ์ดํธ ์์ฑ(SSG)์ ํ์ฉํ ์ ์์ต๋๋ค.
// pages/orders.js (Next.js ์์ )
import React from 'react';
import OrderList from '../components/OrderList';
const OrdersPage = () => {
return (
<div>
<h1>์ฃผ๋ฌธ ๋ด์ญ</h1>
<OrderList />
</div>
);
};
export async function getServerSideProps() {
// SSR์ ํตํด ์ด๊ธฐ ๋ฐ์ดํฐ ํ์นญ ๊ฐ๋ฅ (์: React Query์ prefetch ์ฌ์ฉ)
// ์ด ์์ ์์๋ ๊ฐ๋จํ๊ฒ ๋น props๋ฅผ ๋ฐํ
return { props: {} };
}
export default OrdersPage;
Next.js๋ฅผ ์ฌ์ฉํ๋ฉด, ํ์ด์ง ์ ํ ์ ํ์ํ ๋ฐ์ดํฐ๋ง ์๋ฒ์์ ๋ฏธ๋ฆฌ ๋ก๋ํ ์ ์์ผ๋ฏ๋ก ์ด๊ธฐ ๋ก๋ฉ ์๊ฐ์ ๋จ์ถํ๊ณ SEO์๋ ๊ธ์ ์ ์ธ ํจ๊ณผ๋ฅผ ์ค ์ ์์ต๋๋ค.
๊ฒฐ๋ก
์๋ฒ ํต์ ๊ณผ ๋ฐ์ดํฐ ํ์นญ ์ต์ ํ๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฑ๋ฅ๊ณผ ์ฌ์ฉ์ ๊ฒฝํ์ ์ง๋ํ ์ํฅ์ ๋ฏธ์นฉ๋๋ค. Axios๋ fetch API๋ฅผ ํตํด ๊ธฐ๋ณธ์ ์ธ HTTP ํต์ ์ ๊ด๋ฆฌํ๊ณ , SWR๊ณผ React Query์ ๊ฐ์ ๋ฐ์ดํฐ ํ์นญ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋์ ํ๋ฉด, ์บ์ฑ, ์๋ ์ฌ๊ฒ์ฆ, ๋ฐฑ๊ทธ๋ผ์ด๋ ์ ๋ฐ์ดํธ ๋ฑ ๋ค์ํ ๊ธฐ๋ฅ์ ํตํด ์ต์ ๋ฐ์ดํฐ๋ฅผ ์์ ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
ํต์ฌ ์ ๋ต์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ๊ณตํต API ํด๋ผ์ด์ธํธ ์ค๊ณ: Axios ์ธํฐ์ ํฐ๋ฅผ ํ์ฉํ ๊ณตํต ์์ฒญ ๊ด๋ฆฌ๋ก, ์๋ฌ ์ฒ๋ฆฌ์ ์ธ์ฆ ๋ฑ์ ๋ก์ง์ ์ค์์์ ๊ด๋ฆฌํฉ๋๋ค.
- ๋ฐ์ดํฐ ์บ์ฑ ๋ฐ ์ฌ๊ฒ์ฆ: SWR๊ณผ React Query๋ฅผ ํ์ฉํ์ฌ ๋ถํ์ํ ๋คํธ์ํฌ ์์ฒญ์ ์ค์ด๊ณ , ์ฌ์ฉ์์๊ฒ ํญ์ ์ต์ ๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํฉ๋๋ค.
- ์ ์ญ ์ํ์ ๋ก์ปฌ ์ํ ๋ถ๋ฆฌ: ์๋ฒ์์ ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ ์ ์ญ ์ํ์ ๋ถ๋ฆฌํ์ฌ ๊ฐ ์ปดํฌ๋ํธ์์ ๋ ๋ฆฝ์ ์ผ๋ก ๊ด๋ฆฌํจ์ผ๋ก์จ, ์ ์ง๋ณด์์ฑ์ ๋์ ๋๋ค.
- ์ฝ๋ ์คํ๋ฆฌํ ๋ฐ SSR ํ์ฉ: Next.js์ ๊ฐ์ ํ๋ ์์ํฌ๋ฅผ ํตํด ํ์ด์ง๋ณ ๋ฐ์ดํฐ ํ์นญ์ ์ต์ ํํ๊ณ , ์ด๊ธฐ ๋ก๋ฉ ์๋์ SEO๋ฅผ ๊ฐ์ ํฉ๋๋ค.
์ด์ ๊ฐ์ ์ ๋ต์ ํตํด ๋ฐ์ดํฐ ํ์นญ์ ํจ๊ณผ์ ์ผ๋ก ๊ด๋ฆฌํ๋ฉด, ์ฌ์ฉ์์๊ฒ ๋น ๋ฅด๊ณ ์์ ์ ์ธ ์ธํฐ๋์ ์ ์ ๊ณตํ ์ ์์ผ๋ฉฐ, ๊ฐ๋ฐ์๋ ๋ณด๋ค ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ด ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ์์ผ๋ก ๋ฆฌ์กํธ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ ๋, ์๋ฒ ํต์ ๋ฐ ๋ฐ์ดํฐ ํ์นญ ์ต์ ํ ์ ๋ต์ ์ ๊ทน ๋์ ํ์ฌ, ์ ๋ฐ์ ์ธ ์ฑ๋ฅ๊ณผ ์ฌ์ฉ์ ๋ง์กฑ๋๋ฅผ ํฌ๊ฒ ํฅ์์ํค์๊ธธ ๋ฐ๋๋๋ค.
๋๊ธ