타입스크립트 + useInfiniteQuery : 정렬 기능 구현

728x90
반응형

1. 타입 지정

[PostList.tsx]

export type SortList = 'popularity' | 'latest';

function ViewAllBody() {
  const [sortBy, setSortBy] = useState<SortList>('latest');
  
 return (
 
 <St.MainSubWrapper>
  <PostListAdmin queryKey={[QUERY_KEYS.ADMIN]} queryFn={getAdminPostList('admin')} sortBy={sortBy} />
 </St.MainSubWrapper>
 )

▶ 정렬 타입 정하고 useState로 관리 (인기순 / 최신순)

▶ <PostListAdmin> 컴포넌트로 props로 전달

 

2. 코드

[PostListAdmin.tsx]

import { QueryFunctionContext, QueryKey, useInfiniteQuery, useQueries } from '@tanstack/react-query';
import { DocumentData, QueryDocumentSnapshot } from 'firebase/firestore';
import { SortList } from './ViewAllBody';

interface PostListProps {
  queryKey: QueryKey;
  queryFn: (
    context: QueryFunctionContext<QueryKey, undefined | QueryDocumentSnapshot<DocumentData, DocumentData>>
  ) => Promise<QueryDocumentSnapshot<DocumentData, DocumentData>[]>;
  sortBy: SortList;
}

function PostList({ queryKey, queryFn, sortBy }: PostListProps) {
  const { data: posts, fetchNextPage } = useInfiniteQuery({
    queryKey,
    queryFn,
    initialPageParam: undefined as undefined | QueryDocumentSnapshot<DocumentData, DocumentData>,
    getNextPageParam: (lastPage) => {
      if (lastPage.length === 0) {
        return undefined;
      }
      return lastPage[lastPage.length - 1];
    },
    select: (data) => {
      let sortedPosts = data.pages.flat().map((doc) => ({ id: doc.id, ...doc.data() } as PostType));

      if (sortBy === 'popularity') {
        sortedPosts = sortedPosts.sort((a, b) => {
          const likeCountA = a.likeCount ?? 0; // 만약 likeCount가 없다면 0으로 처리
          const likeCountB = b.likeCount ?? 0; // 만약 likeCount가 없다면 0으로 처리

          return likeCountB - likeCountA;
        });
      } else if (sortBy === 'latest') {
        sortedPosts = sortedPosts.sort((a, b) => {
          const createdAtA = a.createdAt ?? 0; // 만약 createdAt이 없다면 0으로 처리
          const createdAtB = b.createdAt ?? 0; // 만약 createdAt이 없다면 0으로 처리

          return createdAtB - createdAtA;
        });
      }
      return sortedPosts;
    }
  });

▶PostListProps에 정렬 타입 정해주기

▶useInfiniteQuery에서 데이터를 가져오고 select 옵션에서 정렬 기능 구현

(1) likeCount (좋아요) : 데이터가 없으면 0 처리를 한 이유는 타입스크립트에서 undefined 관련 오류를 보냈음

(2) 같은 맥락으로 인기순 /최신수으로 구분해서 return 값으로 정렬된 데이터 반환해주기

 

 

 

끝.

반응형