<Suspense/>
, <ErrorBoundary/>
, <ErrorBoundaryGroup/>
등을 제공합니다. 별 다른 노력없이 쉽게 사용할 수 있습니다.
단순히 React의 개념을 확장한 것입니다. <Suspense/>
, <ErrorBoundary/>
, <ErrorBoundaryGroup/>
와 같은 React 개발자에게 친숙한 이름으로 컴포넌트들을 제공합니다.
Suspensive는 개발자가 서버 사이드 렌더링 환경에서도 React Suspense를 점진적으로 채택할 수 있도록 clientOnly를 제공합니다.
대표적인 라이브러리인 TanStack Query로 Suspense 없이 코드를 작성한다면 이렇게 작성합니다.
이 경우 isLoading
과 isError
를 체크하여 로딩과 에러 상태를 처리하고 타입스크립트적으로 data에서 undefined
를 제거할 수 있습니다.
그런데 만약 조회해야 할 api가 더 많아진다고 가정해봅시다.
조회해야 하는 API가 더 많아진다면 이 로딩상태와 에러상태를 처리하는 코드가 더욱 복잡해집니다.
Suspense를 사용하면 타입적으로 코드가 간결해집니다. 하지만 컴포넌트의 깊이는 깊어질 수 밖에 없습니다.
useSuspenseQuery
는 Suspense
와 ErrorBoundary
를 사용하여 외부에서 로딩과 에러 상태를 처리할 수 있습니다.
하지만 useSuspenseQuery
는 hook이기 때문에 부모에 Suspense
와 ErrorBoundary
를 두기 위해 컴포넌트가 분리되어야만 하기 때문에 뎁스가 깊어지는 문제가 있습니다.
Suspensive의 SuspenseQuery 컴포넌트를 사용하면 hook의 제약을 피해 같은 뎁스에서 더욱 쉽게 코드를 작성할 수 있습니다.
SuspenseQuery
를 사용하면 depth를 제거할 수 있습니다.- UserInfo라는 컴포넌트를 제거하고 UserProfile과 같은 Presentational 컴포넌트만 남으므로 테스트하기 쉬워집니다.
이것이 우리가 Suspensive를 만드는 이유입니다
Suspense, ClientOnly, DefaultProps
Next.js와 같은 프레임워크를 사용하다보면 서버에서 Suspense를 사용하기 어려울 때가 있습니다.
혹은 서버에서 Suspense
를 사용하고 싶지 않을 때가 있습니다.
이럴 때 Suspensive의 ClientOnly를 사용하면 쉽게 해결할 수 있습니다.
ClientOnly
를 감싸주기만 하면 해결됩니다.
혹은 Suspensive의 Suspense에는 clientOnly prop을 활용해 이러한 경우를 쉽게 대응할 수 있습니다.
간단하죠?
그런데 개발을 하다보면 Suspense에 일일이 fallback을 넣어주기 어려울 때가 있습니다.
특히 Admin과 같은 제품을 할 때 디자이너가 일일이 지정해주지 않는 경우가 있어서 기본값을 주고 싶을 때가 있습니다.
그럴 때 DefaultProps
를 활용해보세요.
기본 fallback이 바로 나오는 것보다는 FadeIn과 같은 효과를 주고 싶을 때가 있습니다.
그렇다면 FadeIn
을 활용해보면 어떨까요?
당연히 기본 fallback을 Override하고 싶다면 그냥 넣어주면 됩니다.
디자이너가 이 부분에 기본 Spinner
보다 Skeleton
으로 동작하도록 지원해달라고 하네요~! 그냥 넣으면 되어요.
ErrorBoundary, ErrorBoundaryGroup
ErrorBoundary의 fallback 외부에서 ErrorBoundary를 reset하고 싶을 때 resetKeys를 사용해야 합니다.
이는 깊은 컴포넌트의 경우 resetKey
를 전달해야 하는 문제가 있습니다. 또한 state를 만들어 resetKey
를 전달해야 하는 문제가 있습니다.
Suspensive가 제공하는 ErrorBoundary와 ErrorBoundaryGroup을 조합하면 이러한 문제를 매우 단순히 해결할 수 있습니다.
ErrorBoundaryGroup
을 사용해보세요.
그런데 ErrorBoundary를 사용하다보면 특정 Error에 대해서만 처리하고 싶을 때가 있습니다.
그럴 때에는 Suspensive가 제공하는 ErrorBoundary
의 shouldCatch
를 써보세요. 이 shouldCatch
에 Error Constructor를 넣으면 해당 Error에 대해서만 처리할 수 있습니다.
혹은 반대로 그 Error만 빼고 처리할 수도 있습니다.
그럴 때에는 shouldCatch
에 callback을 넣어서 처리할 수 있습니다.