inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

Next + React Query로 SNS 서비스 만들기

인피니트 스크롤링

무한스크롤 구현시 발생하는 문제

716

김용민

작성한 질문수 74

0

스크린샷 2024-01-23 오후 9.06.06.png강의 수강중에, 배운 무한스크롤을 바탕으로 개인 프로젝트를 진행중입니다.
위의, 데이터를 받아오는 것을 보면, 처음에는 2개를 불러오고, 그 이후에는 계속 5개를 불러오는데, 제가 원하는 방식은 처음부터 끝까지 5개씩 계속 일정하게 불러오는 것을 원합니다. 이유를 찾을려고 여러가지 검색을 해보며 해봤는데도, 해결되지않아서 질문드립니다. 이 경우 의심해볼 수 있는 부분은 어떤 부분이 있을까요?

최상위 페이지에서 아래와 같이 prefetch를 해오고

type HomeProps = {
  params: {
    category: string;
  };
};

const CategoryDetailPage: React.FC<HomeProps> = async ({ params }) => {
  const { category } = params;

  const queryClient = new QueryClient();
  const college = category;

  // 서버에서 불러온 데이터를 클라이언트의 리액트 쿼리가 물려받음.(하이드레이트)
  await queryClient.prefetchInfiniteQuery({
    queryKey: ['posts', college],
    queryFn: ({ pageParam = 1 }) => getFilteredPosts(college, { pageParam }), // searchParams 전달
    // 커서 값
    initialPageParam: 0
  });

  // hydrate라는 것은 서버에서 온 데이터를 클라이언트에서 그대로, 물려받는 것 이다.
  const dehydratedState = dehydrate(queryClient);

  return (
    <HydrationBoundary state={dehydratedState}>
      <Container>
        <ListingContainerTest />
      </Container>
    </HydrationBoundary>
  );
};

export default CategoryDetailPage;

실제 무한스크롤을 사용하는 곳은 아래와 같이 사용하고 있습니다.

'use client';

import { getFilteredPosts } from '@/app/lib/getFilteredPosts';
import { useInfiniteQuery } from '@tanstack/react-query';
import { usePathname } from 'next/navigation';
import { Fragment, useEffect } from 'react';
import { useInView } from 'react-intersection-observer';
import ClimbingBoxLoader from 'react-spinners/ClimbingBoxLoader';

import EmptyState from '../EmptyState';
import ListingGrid from './ListingGrid';

const ListingCard = () => {
  const path = usePathname();
  // ['', chss]
  const college = path.split('/')[1];

  const {
    data: listings,
    fetchNextPage,
    hasNextPage,
    isFetching,
    isError
  } = useInfiniteQuery({
    queryKey: ['posts', college],
    queryFn: ({ pageParam = 1 }) => getFilteredPosts(college, { pageParam }),
    initialPageParam: 0,
    // 가장 최근에 불러왔던 게시글
    getNextPageParam: (lastPage) => lastPage.studyList.at(-1)?.id,
    staleTime: 60 * 1000,
    gcTime: 300 * 1000
  });
  // lastPage.jobList.at(-1)?.id,
  const { ref, inView } = useInView({
    // div가 보이고나서 몇픽셀 정도의 이벤트가 호출될 것 인가? 보이자마자 바로 호출.그래서0
    threshold: 0,
    // 몇초후에 딜레이 보일것인지.
    delay: 0
  });

  console.log(listings);

  useEffect(() => {
    if (inView) {
      !isFetching && hasNextPage && fetchNextPage();
    }
  }, [inView, isFetching, hasNextPage, fetchNextPage]);

  if (isError || listings?.pages?.length === 0) {
    return <EmptyState />;
  }

  return (
    <>
      <div className="pt-24 grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 2xl:grid-cols-6 gap-8">
        {listings?.pages.map((page) =>
          // Assuming each page has a 'studyList' property
          page.studyList.map((listing: any) => (
            <Fragment key={listing.id}>
              <ListingGrid data={listing} />
            </Fragment>
          ))
        )}
        <div ref={ref} style={{ height: 50 }}></div>
      </div>

      {isFetching && (
        <div className="flex items-center justify-center">
          <ClimbingBoxLoader color="#36d7b7" size={20} />
        </div>
      )}
    </>
  );
};
export default ListingCard;

 

react next.js react-query next-auth msw

답변 1

0

제로초(조현영)

네트워크 탭에서 요청에 대한 response을 볼 때도 처음에는 두 개만 불러오나요? 서버에서 두 개만 주는 건가요?

0

김용민

imageimageimage이렇게 받아오는 것 같습니다.
제가 원하는건 첫 화면에 아래 이미지에 jobList와 studyList의 5개의 데이터를 받아오고 싶은데, 첫번째 데이터가 0, 1 총 2개밖에없어서 현재 2개밖에 안나오는 상황입니다.image현재 아래코드와 같이 캐시된 데이터를 갖고, 데이터를 받아와서, 카테고리 화면을 꾸려주고 있습니다.

import { useQueryClient } from '@tanstack/react-query';
import { usePathname } from 'next/navigation';

import ListingGrid from '../listings/ListingGrid';

type CategoryAllProps = {
  onClick: (value: string) => void;
};

const CategoryAll = ({ onClick }: CategoryAllProps) => {
  const path = usePathname();
  const college = path.split('/')[1];
  const cache = useQueryClient();
  const data = cache.getQueryData(['posts', college]);
  const jobList = data.pages[0].jobList;
  const studyList = data.pages[0].studyList;

  console.log(data);

  return (
    <div className="flex flex-col gap-12 mt-10">
      <div className="flex flex-col gap-6 shadow-md p-8 rounded-md border-[1px] border-gray-100">
        <div className="font-bold text-gray-700 text-xl">스터디 · 프로젝트 모집</div>
        <div className="flex flex-row gap-2 flex-wrap">
          {studyList.map((studyData: any, index: any) => (
            <ListingGrid key={index} data={studyData} />
          ))}
        </div>
        <div
          className="flex font-md text-gray-500 text-sm cursor-pointer ml-auto"
          onClick={() => onClick('study')}>
          더 보기
        </div>
      </div>
      <div className="flex flex-col gap-6 shadow-md p-6 rounded-md border-[1px] border-gray-100">
        <div className="font-bold text-gray-700 text-xl">취업 정보 교류</div>
        <div className="flex flex-row gap-2 flex-wrap">
          {jobList.map((jobData: any, index: any) => (
            <ListingGrid key={index} data={jobData} />
          ))}
        </div>
        <div
          className="font-md text-gray-500 text-sm cursor-pointer ml-auto"
          onClick={() => onClick('info')}>
          더 보기
        </div>
      </div>
    </div>
  );
};

export default CategoryAll;

0

제로초(조현영)

네, 그러니까 왜 서버가 2개만 주나요? 서버쪽 코드는 제가 모릅니다. 프론트에서 요청을 잘못해서 서버에서 2개만 주는 거 아닌가요?

prefetchQuery의 queryFn에 넣은 함수에서 지금 서버쪽에 2개만 받아오도록 하고있는 것 같습니다. 그 요청을 알아야합니다.

pageParam = 1 을 주신 것도 의심가는 부분입니다. pageParam은 기본값이 0인데 그걸 다시 1로 바꾸시는 이유가 뭔가요?

캡처링부분 질문있습니다.

0

76

2

깃에 소스코드를 찾을 수 없습니다.

0

113

2

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

0

98

1

import 파일 경로를 찾지 못 해서 에러가 발생합니다.

0

111

2

css 라이브러리 추천 부탁드립니다

0

141

2

팔로우 추천 목록이 빈 배열로 들어옵니다.

0

133

1

게시물 업로드 시 userId가 undefined로 들어가는 오류

0

119

1

useSuspenseQuery 사용 시 SSR 401 이슈 관련

0

172

1

리액트 쿼리 useinfinitequery 무한스크롤 구현 시 페이지가 이동할 경우 데이터가 보존되게 할 수 있나요??

0

184

3

폴링이 필요없는 이유

0

93

2

next Request Memoization과 react cache

0

110

2

seo 최적화 기준은 데이터 fetching인가요 아님 데이터 렌더링인가요?

0

84

2

next.js 서버fetch 에러 fallback ui 구현 방법

0

173

2

프레임워크 여론 파악법

0

125

2

필터옵션이 많은 페이지에서 서버 fetch를 하는게 맞는걸까요??

0

103

2

서버 fetch suspense 로 감싸고 새로고침 시 잠시 빈 화면이 노출된 후 fallback ui가 노출됩니다.

0

102

2

template.tsx 내 서버fetch 응답값과 클라이언트 컴포넌트 상태값 싱크가 맞지 않는 이슈

0

66

2

Auth.js 사용 시 authorize 함수가 호출되지 않습니다

0

132

2

next.js 에서 로그인에 관하여

0

138

1

Next의 route handler에 대한 질문이 있습니다.

0

101

2

게시판 리스트 만들때 use client를 어디서부터 집어넣어야할지 모르겠습니다

0

98

2

프라이빗 폴더를 해야 하는 이유가 모호한 것 같아요.

0

85

2

vanilla-extract 못찾는 문제

0

230

2

fetch 캐싱과 revalidate 관련

0

85

2