ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 냅다 시작하는 리액트 쿼리 (예제편)
    React.js & Next.js 2022. 12. 27. 21:53

    냅다 시작하는 리액트 쿼리 (예제편)

    $ npx create-next-app test --typescript
    

     

    $ yarn add axios @tanstack/react-query
    

    _app.tsx

    // 🗂/pages/_app.tsx
    
    import React from 'react';
    import type { AppProps } from 'next/app';
    import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
    
    function MyApp({ Component, pageProps }: AppProps<any>) {
      const [queryClient] = React.useState(() => new QueryClient());
    
      return (
        <QueryClientProvider client={queryClient}>
          <Component {...pageProps} />
        </QueryClientProvider>
      );
    }
    
    export default MyApp;
    
    1. QueryClient로 인스턴스 생성합니다
    2. QueryClientProvider로 <Component/> 를 감싸 query로 global 하게 관리할 수 있도록 만듭니다

    hooks/movie

    기본적인 TMDB api 를 사용했습니다.

    The Movie Database (TMDB)

     

    The Movie Database (TMDB)

    Welcome. Millions of movies, TV shows and people to discover. Explore now.

    www.themoviedb.org

    먼저 파라미터로 이름을 받는 것 보다는 기본 동작원리를 설명하기 위해 미리 검색될 결과물을 설정해줬습니다 (spiderman)

    await axios.get(`https://api.themoviedb.org/3/search/movie?api_key=쿼리키&language=en-US&query=spiderman`);
    

    해당 axios 요청을 리턴하는 함수를 선언했습니다.

    const fetchMovies = async () => {
      try {
        const response = await axios.get(
          `https://api.themoviedb.org/3/search/movie?api_key=쿼리키&language=en-US&query=spiderman`
        );
    
        return response.data.results;
      } catch (err) {
        console.error(err);
      }
    };
    

    눈으로 직접 에러를 axios 단에서 보고자하는 경우가 아니라면, try catch 로 감싸지 않더라도 react-query 내에서 캐치가 가능합니다.

    const fetchMovies = async () => {
        const response = await axios.get(
          `https://api.themoviedb.org/3/search/movie?api_key=쿼리키&language=en-US&query=spiderman`
        );
        return response.data.results;
    };
    

    에러를 직접 던져본다면 에러를 캐치할 수 있겠죠?

    const fetchMovies = async () => {
        const response = await axios.get(
          `https://api.themoviedb.org/3/search/movie?api_key=쿼리키&language=en-US&query=spiderman`
        );
    
        throw new Error('사실 에러에욥');
        return response.data.results;
    };

    이후 react-query의 useQuery 메서드를 사용하여 키를 설정하고, 해당 함수를 바인딩합니다

    const useMovies = () => {
      return useQuery(['movies'], () => fetchMovies());
    };
    

    전체 코드

    import axios from 'axios';
    import { useQuery } from '@tanstack/react-query';
    
    const fetchMovies = async () => {
      try {
        const response = await axios.get(
          `https://api.themoviedb.org/3/search/movie?api_key=쿼리키&language=en-US&query=spiderman`
        );
    
        return response.data.results;
      } catch (err) {
        console.error(err);
      }
    };
    
    const useMovies = () => {
      return useQuery(['movies'], () => fetchMovies());
    };
    
    export { useMovies, fetchMovies };
    

    useMovies, fetchMovies 를 둘 다 export 할 수 있습니다.

    1. 뷰 로직에서 useQuery를 다시 사용할 경우에는 fetchMovies를 사용합니다
    2. 뷰 로직에서 uesQuery를 사용하지 않을 경우에는 useMovies를 사용합니다

    pages/index.tsx

    import React, { useEffect } from 'react';
    import { useMovies } from '@hooks';
    
    const ReactQueryComponent = () => {
      const {
        isSuccess: movieIsSuccess,
        isLoading: movieIsLoading,
        isError: movieIsError,
        data: movieData,
        error: movieError,
      } = useMovies();
    
      if (movieIsLoading) {
        return <span>Loading...</span>;
      }
    
      if (movieIsError) {
        console.warn('error', movieError);
        return <span>Error... </span>;
      }
    
      if (movieIsSuccess && movieData.length === 0) {
        return <span>There is no data...</span>;
      }
    
      return (
        <div>
          <h1>Hello React Query!</h1>
    
          {movieData.slice(0, 5).map((item: any) => (
            <div key={item.id}>{item.title}</div>
          ))}
        </div>
      );
    };
    
    export default ReactQueryComponent;
    

    유용한 기능과 메서드는 다음 장에 다루도록 하겠습니다 

    댓글

Designed by Tistory.