본문 바로가기
개발/React

Suspense

by 안뇽! 2022. 8. 10.
반응형

react18에 suspense가 정식기능으로 나왔다.

 

그런데 

if(loading) return <span>로딩</span>
if(error) return <span>에러</span>
else return (페이지)

위와 같이 하지 않고

아래와 같이 suspense를 쓰는게 왜 좋은것일까??

<Suspense fallback = {<span>로딩</span>}>
	<ErrorBoundary fallback={<span>에러</span>}>
      <div>{data}</div>
    </ErrorBoundary>
 </Supense>

 

 

먼저 return을 로딩,에러,데이터 별로 분기하는것이 안좋은 이유는 다음과 같다.

(사실 나는 체감으로 느껴보진 못했던 것들이었음..)

 

1.  기본적으로 데이터 로딩과 UI 랜더링이라는 두 가지 전혀 다른 목표가 하나의 컴포넌트 안에 커플링(coupling)되어 코드가 읽기가 어려워짐

 

2. 초기 랜더링 후에 데이터 로딩 후 다시 랜더링을 수행하는 방법은 좋은 방법이 아님. (리렌더링은 줄이는게 좋음)

 

3. 비동기통신을 하면 코드가 순서대로 작동한다는 보장이 없기에 싱크가 맞지않는 UI가 유저에게 보여질 수 있음.

 

4. 상위 컴포넌트의 데이터 로딩이 끝나야지만 하위 컴포넌트의 데이터 로딩이 시작될 수 있기 때문에 Waterfall현상이 나타난다.
Waterfall현상은 이 글에서 이해하기 쉽게 설명하고 있음

 

그럼 Suspense를 사용하면 어떤것들이 좋아지는 것일까??

 

만약 코드를 이렇게 작성하면

const {data,loading,error} = useQuery(...)

useEffect(()=>{...},[data])

if(loading) return <span>로딩</span>
if(error) return <span>에러</span>
else return (페이지)

 

컴포넌트 렌더링 -> data fetching -> 로딩중이면 로딩화면 렌더링 -> data 수신하면 유저에게 보여줄 화면 렌더링

 

순서로 동작하게 된다.

 

하지만

 

suspense를 사용하면

import fetchData from "./fetchData";

...

<Suspense fallback = {<span>로딩</span>}>
	<ErrorBoundary fallback={<span>에러</span>}>
      <div><Data resource = {fetchData(1)} /></div>
    </ErrorBoundary>
 </Supense>

컴포넌트를 렌더링한 다음에 data fetching을 하는 것이 아니라

 

data fetching후에, data 수신이 완료되면 렌더링을 하게 된다.

 

때문에 waterfall 현상이 줄어들게 된다(부모 컴포넌트와 자식컴포넌트간 렌더링 시간차 감소)

 

또한 코드측면에서도 UI와 data fetching이 분리되어 가독성이 좋아진다.

 


 

사실 Suspense를 사용한게 이전에 리코일을 사용하면서 원리도 모른채 사용법만 보면서 사용한게 다라서 정확히 이해를 하진 못했다.

 

직접 사용하면서 우당탕탕 우여곡절을 겪어보면 이해가 가는 것들이 많을 것 같다.

 

그리고 Suspense는 SSR측면에서 활용 가능성이 무궁무진하다고 하다.

 

나중에 Suspense 생태계가 지금보다 확장되어서 더 많은 활용사례들이 나오길 기대해본다.

 


 

 

참고문서 

https://www.daleseo.com/react-suspense/  이게 가장 좋은 듯, Waterfall현상을 이해하기 쉽게 설명하고 있음

 

https://velog.io/@bbaa3218/React-Suspense%EB%9E%80

 

 

반응형