슬기롭게 비동기 처리하기

김준엽·2022년 5월 12일
0

React

목록 보기
5/11

일반적으로 컴포넌트에서 비동기 처리를 하면 로딩, 성공, 실패 처리를 동시에 수행하는 아래 같은 소스코드를 볼 수 있습니다.

function Profile() {
  const foo = useAsyncValue(() => {
    return fetchFoo()
  })
  
  const bar = useAsyncValue(() => {
    if (foo.error || !foo.data) {
      return undefined
    }
    return fetchBar(foo.data)
  })
  
  if (foo.error || bar.error) return <div>로딩에 실패했습니다.</div>
  if (!foo.data || !bar.data) return <div>로딩중입니다.</div>
  return (/* foo와 bar로 적합한 처리하기*/)
}

이게 좋은 소스코드일까요? 아닙니다. 비동기 함수가 늘어날수록 처리해야 하는 경우가 많이 증가합니다. 나중에는 가독성이 매우 떨어져 유지보수 하기가 힘들어집니다. 그러면 어떻게 해야 할까요?

성공하는 경우와 실패하는 경우, 로딩 중인 경우를 나누어 각각 그 경우에만 집중하는 소스코드를 구성해야 합니다. React v17 이전까지는 그런 컴포넌트를 구성하기가 어려웠는데 React v18 부터 Suspense로 비동기 처리 시 복잡도를 줄일 수 있습니다.

function FooBar() {
  const foo = useAsyncValue(() => fetchFoo())
  const bar = useAsyncValue(() => fetchBar(foo))
  
  return <div>{foo}{bar}</div>
}

비동기 처리가 성공하는 경우만 집중한 컴포넌트입니다.

<ErrorBoundary fallback={<MyErrorPage />}>
  <Suspense fallback={<Loader />}>
    <FooBar />
  </Suspense>
</ErrorBoundary>

로딩 상태는 Suspense에서 처리하고 에러 상태는 ErrorBoundary가 처리합니다. 이 형태를 이용하면 복잡도가 낮고 가독성이 좋고 비즈니스 로직이 쉽게 파악가능합니다.

Suspense는 아래 라이브러리를 이용해서 사용할 수 있습니다.

  • Recoil : Async Selector
  • SWR, React Query : { suspense: true } option

라이브러리를 사용하지 않고 비동기 함수를 처리하는 방법은 공식문서를 참고하시면 됩니다.

ErrorBoundary는 함수형 컴포넌트에서 구현되지 않는 기능들을 사용하기 때문에 클래스 컴포넌트로만 구현 가능합니다. react-error-boundary 라이브러리를 이용하거나 직접 구현해서 사용합니다.

예제

Recoil을 이용해 비동기 함수를 다루었습니다.

선언적으로 컴포넌트를 구성해야 한다. 컴포넌트 바로 하단에 작성, 함수안에 비동기를 실행하면 안된다. suspense가 감지하지 못하니깐

참고

https://toss.im/slash-21/sessions/3-1
https://www.daleseo.com/react-suspense/
https://maxkim-j.github.io/posts/suspense-argibraic-effect
https://jbee.io/react/error-declarative-handling-1/
https://varletc0nst.tistory.com/39
https://velog.io/@rkd028/React-ErrorBoundary-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%EC%97%90%EB%9F%AC-%ED%95%B8%EB%93%A4%EB%A7%81-%ED%95%98%EA%B8%B0
https://sangmin802.github.io/Study/Think/error%20boundary/
https://kentcdodds.com/blog/use-react-error-boundary-to-handle-errors-in-react

profile
프론트엔드 개발자

0개의 댓글