SSG(static-site-generation)으로 Pre-rendered 된 페이지에서
CSR로 불러오는 아이템 목록 컴포넌트에 Suspense 적용하기
전체를 SSR로 만드는 것보다
SSG를 기본으로 CSR로 request가 있을때마다 일부 데이터를 보내주는게
더 효율적이고 서버부담이 적음.
비동기 처리를 우아하게.
Cumulative Layout shift를 손쉽게 방지할 수 있다.
https://velog.io/@sun1301/FDBS-isValidating-and-loading
컴포넌트의 Depth가 늘어남에 따라 어느 컴포넌트에서 Error가 발생하는지. 로딩이 어느 단계에서 발생되는지 추적하는게 힘들어졌다.
isLoading 등으로 로딩상태를 일일이 처리하다보니 코드가 직관적이지 않고 지저분해지게 되었음.
관심사의 분리가 필요.
//적용 이전
const FictionsWithParams: NextPage<FictionsResponse> = ({
keywords,
categories,
nationalities,
}) => {
return (
...
{!isLoading &&
<FictionList
checkedItems={checkedItems}
checkedNationalities={checkedNationalities}
checkedGenres={checkedGenres}
checkedSortings={checkedSortings}
isChecked={isChecked}
/>
}
...
)
}
///적용 이후
//Suspense는 SSR 미지원. Dynamic하게 import.
const DynamicFictionListWrapper = dynamic(
() => import(`@components/fictionListWrapper`),
{
suspense: true,
}
);
const FictionsWithParams: NextPage<FictionsResponse> = ({
keywords,
categories,
nationalities,
}) => {
return (
...
<ErrorBoundary>
<Suspense
fallback={
<FadeLoader
className=" mx-auto"
height={15}
width={5}
radius={2}
margin={2}
color={"#000000"}
/>
}
>
//FictionList를 DynamicFictionList 안으로
<DynamicFictionListWrapper
checkedItems={checkedItems}
checkedNationalities={checkedNationalities}
checkedGenres={checkedGenres}
checkedSortings={checkedSortings}
isChecked={isChecked}
/>
</Suspense>
</ ErrorBoundary>
}
...
)
}
-> 컴포넌트에 Dynamic import 적용.
-> SWR suspense opion 사용.
-> key값이 null일때 empty data를 return해야함.
-> SWR이 Suspense와 동기적으로 데이터를 읽는 rule을 위반?
//해결책
const [ready, setReady] = useState(false)
const { data } = useSWR(ready ? '/api' : null, { suspense: true }) // <- we can't throw promise here!
useEffect(() => { setReady(true) }, [])
console.log(data)
https://github.com/vercel/swr/pull/357
-> shallow option을 넣더라도 리렌더링 발생.
-> useEffect를 컴포넌트 구조 최상층으로 올리고 종속성 배열을 isChecked로 변경.
-> useEffect를 올바른 위치에서, 종속성 배열을 정확하게.