Skip to content

종길 기록 공간

jgjgill edited this page Oct 1, 2023 · 12 revisions

응집도에 대해 학습하고 공유하기 Colocation

react query 관련

  • 폴링 => 채팅 관련
  • 낙관적 업데이트 => 좋아요, 팔로우 버튼
  • 쿼리 무효화 => 채팅 관련
  • 무한 스크롤 => 게시판
  • suspense => undefined 처리, 로딩

인증 인가 관련 api가 두 번 호출되는 문제 해결하기

현재 혼콕에서는 인증/인가 관련된 역할을 react query를 통해 처리하고 있다. useUser라는 훅으로 만들어서 간편하게 사용하고 있는데 유저가 페이지에 처음 진입하거나 새고고침을 할 때 관련 api가 두 번 호출되는 문제가 발생했다.

스크린샷 2023-09-22 오전 3 38 41

우선 어디서 호출되는지 살펴봤을 때 페이지 내에서 훅이 두 군데 이상 사용이 되어도 횟수는 두 번만 발생하고 있었다. 그래서 useUser를 하나씩 없애보며 네트워크를 확인하는 방식으로 문제 상황을 접근했다.

하나씩 파고들면서 파악한 문제 코드는 다음과 같다.

Layout.tsx

const Layout = () => {
  const { userIsLoading } = useUser();

  if (userIsLoading) return;

  return (
    <div className="mx-auto h-screen max-w-[767px] pb-24 pt-28 font-OAGothic">
      <Outlet />
    </div>
  );
};

전체 레이아웃에서 기본적으로 user에 대한 검증을 실시하고 있다. 이때 loading 상태면 미리 return을 처리하여 내부 렌더링, 즉 하위 내용(파일)들을 호출하지 않도록 한 것이다. 여기서 useUser가 두 번 발생하게 되는 것인데 loading값의 초기 상태가 true에서 false로 변할 때 내부 파일들을 불러오면서 useUser가 다르게 인식되는 걸로 파악이 된다.

그래서 userIsLoading에 대한 return 처리를 없애면 다음과 같이 한 번만 호출되는 것을 확인할 수 있다.

스크린샷 2023-09-22 오전 4 35 07

이때 데이터가 없는 경우, 로딩 상태에 대한 처리가 필요하다.

이를 위해 suspense를 적용할 수 있다. suspense를 통해 내부에는 성공하는 상황만을 가정하고 외부에서 로딩에 대한 처리를 담당하게 한다.

적용 코드는 다음과 같다.

App.tsx

const App = () => {
  return (
    <QueryClientProvider client={queryClient}>
      <Suspense>
        <ToastProvider>
          <RouterProvider router={router} />
        </ToastProvider>
      </Suspense>
      <ReactQueryDevtools initialIsOpen />
    </QueryClientProvider>
  );
};

useUser.ts

const { data: user, isLoading: userIsLoading } = useQuery<User>({
  queryKey: userKeys.user,
  queryFn: getUser,
  suspense: true
});

react query에서 undefined를 없애기 위한 과정

배열 데이터에서는 빈 배열을 활용 → 객체 형태에서는?

코드에서의 지저분함, 분기처리, 읽기 어려움

현재 우리가 작성하는 코드에서 데이터가 없는 상황을 고려할 필요가 있을까?

suspenseerror boundary 함께 생각해보기

데이터가 있는, 성공한 상황만을 가정

로딩과 실패에 대한 고려는 코드를 작성하는 내부에서 우리의 관심사가 아니다.

외부에서 처리

선언적인 코드 작성

suspense 를 알아보자.

error boundary 도 비슷한 형태로 코드가 쓰인다.

react query 에서는 어떻게 할 수 있을까?

undefined 가 나오는 상황은 아직 데이터가 오지 않은 상황을 고려하기 때문

suspense 를 사용하면 데이터가 오지 않은 상황, 즉 로딩인 상황에 대한 처리를 외부에 위임

하지만 react query 에서는 아직 타입적으로 지원하지 않는다.

suspense 를 사용해도 여전히 undefined 로 남아있는 상황

결국에는 타입적으로 문제가 되는 상황이다.

이를 해결하기 위해 여러 방안이 적용할 수 있다.

현재 혼콕 개발 일정 및 팀 규칙을 고려해서 최선의 선택을 내리는 것이 필요하다.

이를 해결하기 위해 타입스크립트에서 assert 를 활용할 수 있다.

assert 에 대한 설명

가장 빠르면서도 쉽게 적용할 수 있는 방법으로 보여진다.

react query 내부 코드에 대한 학습 및 이해없이도 누구나 쉽게 사용할 수 있다.

현재 혼콕 서비스를 생각했을 때 가장 최적의 방안으로 보여져 해당 방식으로 undefined 를 처리했다.

예정된 개발 일정이 지나고 상대적으로 여유로워진 시기에 관련 내용에 대한 추가 학습을 진행했다.

이미 undefined 에 대한 고민과 없애기 위한 노력들이 존재했다.

suspensive 라는 라이브러리를 사용하거나 커스텀훅으로 만들 수도 있다.

usequery 를 사용할 때 타입적으로 지원하지 않았던 부분을 보완해주는 것이다.

관련 내용…

react query 버전5에서는 useSuspenseQuery를 공식적으로 지원한다.

버전이 맞다면 공식 훅을 사용해도 좋다.

참고 자료

  • suspense에 관한 문서
  • assert에 관한 문서
  • suspensive 코드
  • undefined관련 이슈 링크
Clone this wiki locally