강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

변재정님의 프로필 이미지
변재정

작성한 질문수

Next.js 까보기: "쓸 줄 아는 개발자"에서 "알고 쓰는 개발자"로

왜 server action 이 필요할까?

useInfiniteQuery promise와 react use 사용시 페이지 무한 로딩

작성

·

25

·

수정됨

0

리액트 쿼리의 suspense 스트리밍 기능 구현 중 버그가 발생해 인사이트를 얻고자 질문드립니다.

상위 컴포넌트에서 useInfiniteQuery로 promise를 반환하고, 해당 promise를 자식 컴포넌트의 props로 넘긴 뒤 React의 use hook으로 감싸서 data를 반환하도록 구현했습니다. 그리고 promise를 throw하는 자식 컴포넌트를 Suspense로 감싸서 promise를 캐치하도록 했는데요.

페이지 렌더링 자체는 정상적으로 되는데, request가 완료되지 않는 문제가 있습니다. 크롬 개발자도구의 Network 탭에서 document를 확인하면 "Caution: request is not finished yet"이라는 경고가 표시됩니다.

TanStack Query 공식 문서에도 useInfiniteQuery의 promise 사용 시 "This can be used with React.use() to fetch data"라고 명시되어 있어 React use와 함께 사용하라고 안내하고 있는데, 혹시 이 문제의 원인을 알 수 있을까요?

참고로 prefetch는 안했습니다. 그리고 prefetch 안하는 방법으로 suspense 스트리밍을 구현하고 싶습니다.

 

코드는 아래와 같습니다. 감사합니다!

 

export default function DetailReviewWrapper({ pid, userId }: DetailReviewProps) {
  const { observerRef, isFetchingNextPage, refetch, promise } = useReviewListInfinity({
    userId,
    pid,
  })
  return (
    <Suspense fallback={<DetailReviewLoading />}>
      <DetailReview
        pid={pid}
        userId={userId}
        promise={promise}
        refetch={refetch}
        isFetchingNextPage={isFetchingNextPage}
        observerRef={observerRef}
      />
    </Suspense>
  )
}
export default function DetailReview({
  pid,
  userId,
  promise,
  refetch,
  isFetchingNextPage,
  observerRef,
}: DetailReviewProps) {

  const data = use(promise)

  return (
    <>
      <section>
 <ReviewListView
          userId={userId}
          pid={pid}
          data={data?.list || []}
          className={cn('review-list')}
          refetch={refetch}
          showPoint
        />
        {isFetchingNextPage && <Loading />}
        <div ref={observerRef} />   
   </section>
export function useReviewListInfinity(params: UseReviewListInfinityProps) {
  const section = useSearchParams().get('contentType') as SectionType
  const orderType = useRecoilValue(commentOrderState)
  const filterType = useRecoilValue(filterTypeState)

  const { fetchNextPage, hasNextPage, isFetchingNextPage, isLoading, refetch, promise } = useInfiniteQuery({
    queryKey: [REVIEW_LIST_KEY, params, orderType, filterType, section],
    queryFn: ({ pageParam = 1 }) =>
      getReviewApi({
        uid: params.userId,
        pid: params.pid,
        section,
        pageInfo: {
          curPage: pageParam,
          pageSize: 20,
        },
        orderType: orderType === 'RECOMMENDED' ? 'like' : 'date',
        filterType,
      }),
    select: (data) => {
      return {
        list: data.pages.flatMap((page) => page.data.list),
        info: data.pages[0].data.info,
      }
    },
    getNextPageParam: (lastPage) => {
      const nextPage = lastPage.data.pageInfo.curPage + 1
      return nextPage <= lastPage.data.pageInfo.pageCount ? nextPage : undefined
    },
    initialPageParam: 1,
  })

  const { observerRef } = useIntersectionObserver({
    onScroll: () => {
      if (hasNextPage && !isFetchingNextPage) {
        fetchNextPage()
      }
    },
  })

  return {
    isLoading,
    isFetchingNextPage,
    observerRef,
    refetch,
    promise,
  }
}
const getQueryClient = (): QueryClient =>
  new QueryClient({
    defaultOptions: {
      queries: {
        refetchOnWindowFocus: false,
        refetchInterval: false,
        refetchOnReconnect: true,
        refetchOnMount: true,
        staleTime: Infinity,
        gcTime: Infinity,
        retry: false,
        experimental_prefetchInRender: true,
      },
    },
  })

 

무한 로딩 시 개발자 도구 캡쳐이미지입니다.

스크린샷 2025-11-03 오후 5.42.48.png

 

답변 1

0

안녕하세요, 인프런 AI 인턴입니다. 변재정님.

현재 겪고 계신 문제는 useInfiniteQuery와 React의 use 훅을 사용하여 데이터 페칭을 구현할 때 발생하는 이슈로 보입니다. 예상되는 문제와 해결 방법에 대해 설명드리겠습니다.

문제의 원인

  1. Promise와 Suspense 사용: useInfiniteQuery가 반환하는 Promise를 React의 use 훅으로 감싸서 사용하고 있습니다. 그러나 이 방식은 Suspense와의 호환성이 아직 확실하지 않을 수 있습니다. 특히, Promise가 제대로 완료되지 않으면 영원히 대기 상태에 머물 가능성이 있습니다.

  2. 네트워크 요청 지연: 개발자 도구의 네트워크 탭에서 “Caution: request is not finished yet”이라는 메시지를 확인하셨다면, 이는 네트워크 요청이 완료되지 않고 있는 상태를 의미합니다. 이러한 문제는 서버 응답 지연, CORS 설정, 네트워크 상태 등의 요소로 인해 발생할 수 있습니다.

해결 방법

  1. React Query와 Suspense 설정 확인: React Query의 Suspense 기능을 제대로 활용하려면, useQuery 혹은 useInfiniteQuery에서 반환된 데이터를 다룰 때 특별히 설정을 추가해야 합니다. 예를 들어, suspense: true 옵션을 useInfiniteQuery에 추가하여 Suspense가 제대로 작동하도록 설정합니다.

  2. 네트워크 문제 해결: 네트워크 문제인지 확인하기 위해 서버 로그, 네트워크 상태, CORS 설정 등을 다시 한번 점검해 보시기 바랍니다. 특히, 요청이 끝나지 않는 이유가 서버 측의 문제인지 확실히 파악해야 합니다.

  3. React Query 최신 버전 사용: 사용 중인 React Query 라이브러리가 최신 버전인지 확인하시고, 관련 업데이트를 적용해 보세요. 버그 수정이나 개선 사항이 있을 수 있습니다.

  4. 코드 검토: 페칭 함수(getReviewApi)가 정상적으로 데이터를 반환하는지 재확인하시고, getNextPageParam 함수가 올바르고, 예상되는 페이지를 반환하는지 확인하세요.

더 많은 도움이 필요하시다면, 관련 정보를 토대로 추가적인 디버깅을 하실 수 있는 예제 코드를 React Query 공식 문서에서 찾아보시기 바랍니다.

저는 질문자님의 이해를 돕고자 유사한 문제를 다룬 추가적인 답변 링크를 추천해드리지 못해 아쉽습니다. 현재 베타 기능으로 만족스러운 답변을 드리지 못한 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

변재정님의 프로필 이미지
변재정

작성한 질문수

질문하기