본문 바로가기
카테고리 없음

Next.js에서 Suspense 사용하기

by riversun1 2024. 7. 11.

 

 몇 주전, 팀 프로젝트 기간에

다른 팀의 팀원이 엄청 고민에 빠져있는 것을 보고 무슨 일인지 물어봤다.

 

Suspense를 사용하려는데 서버 컴포넌트에서는 잘 작동하는데

클라이언트 컴포넌트에서 잘 작동이 되지 않는다고 하였다.

 

나는 Next.js 프로젝트를 시작한지 얼마되지 않아서,

suspense의 개념만 알고 사용해본적이 없었어서 도움이 되지 못했다.

 

이번에 생각난 김에 나도 공부해두면 좋을 것 같아서 정리하게되었다.

 

Suspense란?

Suspense는 React에서 비동기 작업(예: 데이터 패칭)을 처리할 때 사용된다.

컴포넌트가 비동기 작업을 완료할 때까지 대기 상태를 표시하도록 도와준다.

import React, { Suspense } from 'react';

const DataComponent = React.lazy(() => import('./DataComponent'));

function MyComponent() {
  return (
    <div>
      <h1>My Component</h1>
      <Suspense fallback={<div>Loading...</div>}>
        <DataComponent />
      </Suspense>
    </div>
  );
}

 

위의 예제에서 DataComponent는 비동기로 로드되며, 로딩 중에는 Loading... 텍스트가 표시된다.

 

 

Next.js는 리액트 기반의 프레임워크로,

서버 사이드 렌더링(SSR)과 정적 사이트 생성(SSG) 기능을 제공한다.

React 18이 도입되면서 Suspense 컴포넌트와 Concurrent Mode가 추가되어

비동기 데이터 로딩을 보다 효율적으로 처리할 수 있게 되었다.

 

하지만, Next.js에서는 클라이언트 컴포넌트에서 Suspense를 사용하는 데 몇 가지 제약이 있다.

 

 

Next.js에서의 Suspense 사용

Next.js에서 Suspense를 사용하려면 몇 가지 사항을 고려해야 한다.

  1. 서버 컴포넌트에서의 사용: Next.js는 기본적으로 서버에서 렌더링된다. 따라서 Suspense는 서버 사이드에서 데이터 패칭을 처리할 때 유용하게 사용될 수 있다.
  2. 클라이언트 컴포넌트에서의 제약: 클라이언트 컴포넌트에서 Suspense를 사용하는 경우, 비동기 데이터 패칭을 직접 처리하지 못할 수 있다. 이는 Next.js의 서버 사이드 렌더링 특성과 연관이 있다.

 

클라이언트 컴포넌트에서 Suspense 사용

다음은 간단한 클라이언트 컴포넌트에서 Suspense를 사용하는 예제이다.

이 예제에서는 데이터를 패칭하고 로딩 상태를 관리하는 방법을 보여준다.

// pages/index.js
import React, { useState, useEffect, Suspense } from 'react';

function fetchData() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('데이터가 로드되었습니다!');
    }, 2000);
  });
}

function DataComponent() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetchData().then((result) => {
      setData(result);
    });
  }, []);

  if (!data) {
    return <div>로딩 중...</div>;
  }

  return <div>{data}</div>;
}

function MyComponent() {
  return (
    <div>
      <h1>내 컴포넌트</h1>
      <Suspense fallback={<div>로딩 중...</div>}>
        <DataComponent />
      </Suspense>
    </div>
  );
}

export default MyComponent;

 

위의 예제에서는 fetchData 함수가 데이터를 2초 후에 반환한다. DataComponent는 useEffect 훅을 사용하여 데이터를 패칭하고, 데이터가 없을 때는 로딩 상태를 표시한다. MyComponent는 Suspense 컴포넌트를 사용하여 DataComponent가 로딩 중일 때 "로딩 중..." 메시지를 표시한다.

 

Next.js에서 권장하는 방법

Next.js에서 비동기 데이터 로딩을 처리할 때는 getStaticProps나 getServerSideProps를 사용하는 것이 좋다.

이를 통해 데이터를 서버 사이드에서 패칭하고 컴포넌트에 전달할 수 있다.

// pages/index.js
import React from 'react';

export async function getStaticProps() {
  const data = await fetchData();
  return {
    props: {
      data,
    },
  };
}

function DataComponent({ data }) {
  return <div>{data}</div>;
}

function MyComponent({ data }) {
  return (
    <div>
      <h1>내 컴포넌트</h1>
      <DataComponent data={data} />
    </div>
  );
}

export default MyComponent;

 

위 예제에서 getStaticProps를 사용하여 데이터를 서버 사이드에서 패칭하고, 이를 컴포넌트에 전달한다.

 

 

결론

Next.js에서 Suspense를 사용하는 것은 가능하지만, 클라이언트 컴포넌트에서의 사용은 제약이 따른다.

비동기 데이터 로딩을 보다 효과적으로 처리하기 위해

Next.js에서 제공하는 getStaticProps나 getServerSideProps를 사용하는 것이 좋다.