OLD/React

[ React ] react-router loader vs react-query useQuery

joseph0926 2023. 8. 22. 20:08

- Router loader

  • loader 함수는 원래 remix라는 react 프레임워크에서 데이터 패칭을 수행하는 하나의 메커니즘이지만, react-router가 최신버전으로 업데이트되면서 해당 메커니즘을 채택하고 사용하기 시작하였습니다.
  • loader는 기본적으로 페이지(컴포넌트)에서 데이터를 패칭합니다

- react-query useQuery

  • react-query는 데이터 패칭, 데이터 변경, 캐시 관리등에 사용되는 react 패키지입니다
  • useQuery는 기본적으로 hook이므로 컴포넌트가 마운트될때 데이터를 패칭합니다

 

- loader vs useQuery

loader는 loader가 정의되어있는 컴포넌트와 매치되는 path가 트리거되면 데이터를 가져옵니다
반면, useQuery는 path가 트리거된 후 매치되는 컴포넌트가 마운트될때 데이터를 가져옵니다
 

 
먼저 데이터를 가져오는것을 시작한 쪽이 loader고, 이후가 react-query입니다
 
 
이렇게 보면 무조건 loader쪽이 좋을거 같지만, loader는 캐시를 지원하지 않는등의 단점도 존재합니다
따라서 자신의 상황에 맞게 사용하는것이 좋을거같습니다
 
아니면 loader와 react-query를 같이 사용하는 방법도 하나의 대안이 될거같습니다 (loader: 미리로딩 / react-query: 캐싱)
ex)

// 상위 컴포넌트
const getAllRoomsQuery = () => {
  return {
    queryKey: ['room'],
    queryFn: async () => {
      const { data } = await customAxios.get('/rooms')
      return data
    },
  }
}

const HomePage = () => {
  const {
    data: rooms,
    isLoading,
    isError,
    error,
  } = useQuery(getAllRoomsQuery())

  return <Home />
}

export const loader = (queryClient: QueryClient) => async () => {
  const rooms = await queryClient.ensureQueryData(getAllRoomsQuery())
  return rooms
}

// 하위 컴포넌트
const RoomPage = () => {
  const rooms = useRouteLoaderData('room')

  return <div>RoomPage</div>
}

// 라우터 정의하는 루트 컴포넌트
 const router = createBrowserRouter([
    {
      path: '/',
      element: <RootLayout />,
      errorElement: <ErrorPage />,
      loader: roomsLoader(queryClient),
      id: 'room',
      children: [
        { index: true, element: <HomePage /> },
        { path: 'room/:roomId', element: <RoomPage /> },
      ],
    },
  ])