๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Lect & Tip/node, Angular, React

REACT Axios, fetch API, SWR, React Query ์„œ๋ฒ„ ํ†ต์‹  ๋ฐ ๋ฐ์ดํ„ฐ ํŽ˜์นญ ์ตœ์ ํ™” ์ปดํฌ๋„ŒํŠธ

by ๊น€๋ฌด์•ผํ˜ธ3ํ˜ธ 2025. 8. 21.
๋ฐ˜์‘ํ˜•

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๋ฅผ ๊ฐœ์„ ํ•ฉ๋‹ˆ๋‹ค.

์ด์™€ ๊ฐ™์€ ์ „๋žต์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ํŽ˜์นญ์„ ํšจ๊ณผ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋ฉด, ์‚ฌ์šฉ์ž์—๊ฒŒ ๋น ๋ฅด๊ณ  ์•ˆ์ •์ ์ธ ์ธํ„ฐ๋ž™์…˜์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ฐœ๋ฐœ์ž๋Š” ๋ณด๋‹ค ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ์‰ฌ์šด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ž์œผ๋กœ ๋ฆฌ์•กํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•  ๋•Œ, ์„œ๋ฒ„ ํ†ต์‹  ๋ฐ ๋ฐ์ดํ„ฐ ํŽ˜์นญ ์ตœ์ ํ™” ์ „๋žต์„ ์ ๊ทน ๋„์ž…ํ•˜์—ฌ, ์ „๋ฐ˜์ ์ธ ์„ฑ๋Šฅ๊ณผ ์‚ฌ์šฉ์ž ๋งŒ์กฑ๋„๋ฅผ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ค์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€