PromleeBlog
sitemap
aboutMe

posting thumbnail
Next.js 데이터 패칭 완전 정복 3 - 병렬, 순차, 조건부 패칭과 클라이언트 사용법
Complete Guide to Data Fetching in Next.js 3 - Parallel, Sequential, Conditional Fetching & Client Usage

📅

🚀

들어가기 전에 🔗

Nextjs 15버전을 기준으로 작성되었습니다. 버전이 올라가면서 API가 변경될 수 있으니, 공식 문서를 참고하시기 바랍니다.
이번 파트에서는 실제 서비스에서 자주 사용되는 fetch 패턴 3가지 —
병렬
,
순차
,
조건부
요청 처리 방식을 살펴봅니다. 또한, 클라이언트 컴포넌트에서 데이터를 가져와야 할 때 어떤 방식으로 처리해야 하는지도 함께 알아보겠습니다.

🚀

병렬 fetch 🔗

여러 개의 데이터를 동시에 요청해야 할 경우,
병렬 fetch
를 사용하면 성능적으로 훨씬 효율적입니다. 이를 위해 JavaScript의 Promise.all()을 활용합니다.

예제 🔗

export default async function Page() {
  const [postsRes, usersRes] = await Promise.all([
    fetch('https://jsonplaceholder.typicode.com/posts'),
    fetch('https://jsonplaceholder.typicode.com/users'),
  ]);
    const posts = await postsRes.json();
  const users = await usersRes.json();
    return (
    <>
      <h2>Posts</h2>
      <ul>
        {posts.map((post: any) => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
      <h2>Users</h2>
      <ul>
        {users.map((user: any) => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </>
  );
}
이렇게 하면 두 요청이
동시에 실행
되기 때문에, 순차적으로 처리할 때보다 빠르게 결과를 얻을 수 있습니다.

🚀

순차 fetch 🔗

어떤 요청의 결과가 다음 요청의 파라미터로 필요한 경우에는
순차적으로
요청을 보내야 합니다.

예제 🔗

export default async function Page() {
  const userRes = await fetch('https://jsonplaceholder.typicode.com/users/1');
  const user = await userRes.json();
    const postsRes = await fetch(
    `https://jsonplaceholder.typicode.com/posts?userId=${user.id}`
  );
  const posts = await postsRes.json();
    return (
    <>
      <h2>{user.name}의 게시글</h2>
      <ul>
        {posts.map((post: any) => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </>
  );
}
이 방식은 사용자의 ID를 알아낸 후, 해당 ID를 기반으로 한 데이터를 요청할 때 유용합니다.

🚀

조건부 fetch 🔗

조건에 따라
데이터를 요청할지 말지 결정해야 할 때도 있습니다. 예를 들어 특정 매개변수가 존재할 때만 데이터를 가져오도록 할 수 있습니다.
export default async function Page({ searchParams }: { searchParams: { userId?: string } }) {
  let posts = [];
    if (searchParams.userId) {
    const res = await fetch(
      `https://jsonplaceholder.typicode.com/posts?userId=${searchParams.userId}`
    );
    posts = await res.json();
  }
    return (
    <>
      <h2>게시글 목록</h2>
      {posts.length > 0 ? (
        <ul>
          {posts.map((post: any) => (
            <li key={post.id}>{post.title}</li>
          ))}
        </ul>
      ) : (
        <p>게시글이 없습니다.</p>
      )}
    </>
  );
}
위와 같이 searchParams에 따라 조건적으로 데이터를 패칭할 수 있습니다.

🚀

클라이언트 컴포넌트에서의 데이터 패칭 🔗

서버 컴포넌트로 처리할 수 없는 데이터는 클라이언트에서 가져와야 할 때가 있습니다. 이때는 React의 useEffect를 사용하거나 SWR 같은 훅 라이브러리를 활용할 수 있습니다.

기본 useEffect 예시 🔗

'use client';
import { useEffect, useState } from 'react';
export default function Page() {
  const [posts, setPosts] = useState<any[]>([]);
    useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then((res) => res.json())
      .then(setPosts);
  }, []);
    return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}
useEffect는 컴포넌트가 마운트된 이후에 실행되므로, 사용자에게는 "로딩 중" 상태를 잠깐 보여줄 필요가 있습니다.

🚀

SWR을 활용한 클라이언트 패칭 🔗

SWR은 React에서 사용하는 데이터 패칭을 더 편리하게 만들어주는 훅입니다. 캐싱, 리패칭, 에러 핸들링 등을 기본으로 제공합니다.
'use client';
import useSWR from 'swr';
const fetcher = (url: string) => fetch(url).then((res) => res.json());
export default function Page() {
  const { data, error, isLoading } = useSWR(
    'https://jsonplaceholder.typicode.com/posts',
    fetcher
  );
    if (isLoading) return <p>로딩 중입니다...</p>;
  if (error) return <p>데이터를 불러오는 데 실패했습니다.</p>;
    return (
    <ul>
      {data.map((post: any) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}
SWR은 내부적으로 스마트한 캐싱과 동기화를 제공하여, 사용자 경험을 향상시킬 수 있습니다.

🚀

결론 🔗

이번 파트에서는 실전에서 매우 유용하게 사용되는
fetch 패턴
3가지(병렬, 순차, 조건부)와, 클라이언트 측 데이터 패칭 방법에 대해 배웠습니다. 특히 SWR은 클라이언트 컴포넌트에서 매우 유용한 도구이니 꼭 익혀두시기 바랍니다.
다음 파트에서는 fetch의 커스터마이징과 캐시 무효화, 그리고 라우트 핸들러를 통한 데이터 통신 방식에 대해 이어서 다루겠습니다.

더 생각해 보기 🔗

참고 🔗