리액트쿼리 적응기(1) useQuery

백민혁·2024년 4월 1일
0

개인프로젝트

목록 보기
6/7
post-custom-banner

목적

개인프로젝트 작업중 리코일로 게시물을 조회 부분을 처리하였는데 리액트쿼리를 사용해서 바꿔보려고 합니다.

React Query의 장점

  • React-Query는 비교적 코드가 쉽고 코드가 단순합니다.
  • Cashing을 통해 애플리케이션 속도를 향상시킵니다.
  • 동일한 데이터에 대한 중복 요청을 제거합니다.
  • 비동기적 선언을 관리하고 React Hook과 유사한 인터페이스를 제공합니다.

FireBase 전체게시물 조회 코드

// 게시글 전체조회
export async function getAllShows(): Promise<PostState[]> {
    try {
        const querySnapshot = await getDocs(collection(db, 'show'))
        const data = querySnapshot.docs.map((doc) => ({
            id: doc.id,
            ...doc.data(),
        }))
        return data as PostState[]
    } catch (error) {
        console.error('게시글 조회 에러', error)
        return []
    }
}

변경전 Recoil을 활용한 게시물 조회 코드

// 모든 게시물
export const getAllPostSelectors = selector<PostState[]>({
    key: 'getAllPostSelectors',
    get: async function fetchData() {
        const data = await getAllShows()

        // 정렬 옵션에 따라 데이터를 정렬
        const sortedData = data.slice().sort((a, b) => {
            return (
                new Date(b.createdAt).getTime() -
                new Date(a.createdAt).getTime()
            )
        })

        return sortedData
    },
})

게시물 조회 사용페이지 코드

  • useRecoilValueLoadable을 활용하여 state에 따라 contents의 여부를 보여주고 필요한 필터를 적용하여 정렬을 맞추는 로직을 구현하였습니다.
const boardList = useRecoilValueLoadable(getAllPostSelectors)
const { contents, state } = boardList

// 게시물의 카테고리와 필터, 정렬을 적용한 데이터
    const filteredAndSortedRows = useMemo(() => {
        if (state === 'hasValue' && contents) {
            const filteredRows = contents.filter(
                (post) => post.category === category,
            )
            return filterFn
                ? filteredRows.sort(filterFn)
                : filteredRows.sort(sortFunction[sortOption])
        }
        return []
    }, [contents, category, sortOption, state])

		{state === 'loading' && <p>로딩 중...</p>}
        {!contents && <p>로드에 실패했습니다.</p>}

	{filteredAndSortedRows.map((post) => (
                    <PostItem key={post.id} post={post} />
                ))}

이 부분을 React-Query를 활용하여 Recoil로 상태관리한걸 제거하고 FireBase 게시물 조회를 활용한 코드를 작성하려고 합니다.
공식문서를 찾아보니 기본적으로 GET 에는 useQuery가, PUT, UPDATE, DELETE에는 useMutation이 사용된다는것을 알 수 있었습니다.

React-Query 세팅 및 api 처리 부터해보겠습니다.

QueryClientProvider

리액트 쿼리 사용을 위해 QueryClientProvider 를 최상단에서 감싸주어야합니다.
쿼리 인스턴스를 생성 후 client={queryClient} 작성해줍니다.

const queryClient = new QueryClient()

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
root.render(
    <React.StrictMode>
        <QueryClientProvider client={queryClient}>
            <RecoilRoot>
                <RouterProvider router={router} />
                {/* <ModalProvider /> */}
            </RecoilRoot>
        </QueryClientProvider>
    </React.StrictMode>,
)
// 전체 게시글 조회
export function useAllShow() {
    return useQuery<PostState[], Error>('allShows', getAllShows, {
        staleTime: 1000 * 60 * 5,
        refetchOnWindowFocus: false,
    })
}

useQuery는 useQuery(queryKey, queryFn, options) 이런 세가지 내용이 들어가고 필요에 경우 다양한 속성들도 사용이 가능합니다.

우선 useQuery를 사용하여 queryKey, queryFn 를 추가하고 속성으로 두가지를 설정하였습니다.

  • staleTime(일정 시간 동안 fresh 상태를 유지해 refetch 트리거가 발생하더라도 refech가 일어나지 않도록 해주는 옵션)
  • refetchOnWindowFocus는 (데이터가 stale 상태일 경우 윈도우 포커싱 될 때 마다 refetch를 실행하는 옵션)
profile
프론트엔드를 공부하는 주니어 개발자입니다.
post-custom-banner

0개의 댓글