[Next.js] CSR 환경에서 Suspense 사용해보았다.
next.js에서 use client 환경에서 서스펜스를 사용해보았다.
이번 Next.js를 사용한 리그오브레전드 정보 프로젝트에서 겪었던 에러입니다.
개요
이번 Next.js 프로젝트에서 Suspense
를 사용하여 로딩작업 중 CSR환경에서 적용되지 않는 이슈가 있었다. 어떤 문제였고 어떻게 해결했는지 작성해보았다.
원인
CSR에서 서스펜스를 사용하려고 시도했을 때 발생했던 문제는 데이터 패칭과 관련된 로딩 상태처리였다. 서스펜스는 데이터가 준비되지 않았을 때 대체 UI를 표시하는 기능이 있지만 Next.js의 use client
환경, 즉 CSR 환경에서 사용할 때 아래와 같은 제한이 있었다.
- React 의 Suspense가 CSR에서 비동기 데이터 로딩을 처리하지 않음
- 그냥 안되는거다. 서스펜스는 클라이언트 환경에서 데이터 패칭을 직접적으로 지원하지 않으며 해당 환경에서 사용할 경우 제대로 작동하지 않거나 서버측에서 미리 데이터를 준비하는 형태가 아니라면 로딩 상태가 안나옴
- 서스펜스는 원래 서버 측에서 데이터를 미리 로드함
- 클라이언트 환경에선 비동기 데이터를 처리하지 못함. 고로 CSR환경에서 서스펜스를 사용하려했던 것 자체가
?
였음..
- 클라이언트 환경에선 비동기 데이터를 처리하지 못함. 고로 CSR환경에서 서스펜스를 사용하려했던 것 자체가
해결방법
해결 방법은 기존에 서스펜스로 로딩처리를 했던 방법에서 useState
를 사용해서 로딩 처리를 적용했다.
const RotationPage = () => {
const [rotationChampion, setRotationChampion] = useState<ChampionInfo[]>([]);
const [loading, setLoading] = useState<boolean>(true);
useEffect(() => {
const fetchData = async () => {
const rotationsChampion = await getChampionRotation();
console.log(rotationsChampion);
// 필터링된 로테이션 챔피언 목록을 상태에 저장
setRotationChampion(rotationsChampion);
setLoading(false);
};
fetchData();
}, []);
return (
<div id="championList" className="w-full bg-lol03 bg-fixed bg-center bg-no-repeat py-[60px] px-[15px]">
{
loading ? (
<div className="loading-ui fixed z-[9999] bg-[#111]">
<p className="bg-loading">쉿! 로테이션 데이터 받아오는중</p>
</div>
) : rotationChampion.length > 0 ? (
// 데이터 출력
) : (
<p>로테이션 챔피언이 없습니다.</p>
)
}
</div>
)
}
마무리
Next.js의 4가지 렌더링 환경에서 작업을 해보면서 어떤 차이점이 있는지 이번 프로젝트를 통해 많이 이해해볼 수 있는 기회인 것 같다. Next.js
의 CSR 환경에서 React의 서스펜스를 사용하는 것은 잘못되었으며, 비동기 데이터를 처리하는 과정에서 사용하는게 옳은 것임을 알 수 있게 되었다. 요즘 공부하면서 사용법에 대해서만 집중하고 어떻게 동작되는지 이해하지 않고 넘어갔던 폐해가 아닐까 싶다.