-
냅다 시작하는 리액트 쿼리 (SSR편)React.js & Next.js 2022. 12. 31. 21:05
$ npx create-next-app test --typescript
$ yarn add @tanstack/react-query
_app.tsx
import React from 'react'; import type { AppProps } from 'next/app'; import { Hydrate, QueryClient, QueryClientProvider } from '@tanstack/react-query'; function MyApp({ Component, pageProps }: AppProps<any>) { const [queryClient] = React.useState(() => new QueryClient()); return ( <QueryClientProvider client={queryClient}> <Hydrate state={pageProps.dehydratedState}> <Component {...pageProps} /> </Hydrate> </QueryClientProvider> ); } export default MyApp;
hydration에 대해 궁금하다면 useEffect를 통해 로그를 찍어볼 수 있습니다
import React, { useEffect } from 'react'; import type { AppProps } from 'next/app'; import { Hydrate, QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { createContext } from 'react'; function MyApp({ Component, pageProps }: AppProps<any>) { const [queryClient] = React.useState(() => new QueryClient()); const MyContext = createContext('default value'); useEffect(() => { console.log('- pageProps.dehydratedState:', pageProps.dehydratedState); }, [pageProps.dehydratedState]); return ( <MyContext.Provider value="Hello World"> <QueryClientProvider client={queryClient}> <Hydrate state={pageProps.dehydratedState}> <Component {...pageProps} /> </Hydrate> </QueryClientProvider> </MyContext.Provider> ); } export default MyApp;
pages/avengers
fetchMovies
const fetchMovies = async (name: string) => { try { const response = await fetch( `https://api.themoviedb.org/3/search/movie?api_key=쿼리키&language=en-US&query=${name}` ); if (!response) throw new Error(`Could not fetch movies -${name}`); return response.json(); } catch (error) { console.error(error); return []; } };
hook 또는 query 폴더로 빼서 관리해도 되지만, 편의를 위해 같이 넣어두었습니다
getStaticProps
서버사이드 렌더링을 지원하기 위해 getStaticProps 메서드를 사용했습니다. getStaticProps 메서드는 빌드시 서버의 요청으로 만들어진 데이터가 고정되어 넘어오는 특징이 있습니다.
export async function getStaticProps() { const queryClient = new QueryClient(); await queryClient.prefetchQuery(['avengers'], () => fetchMovies('avengers')); return { props: { dehydratedState: dehydrate(queryClient) } }; }
whole code
import { dehydrate, QueryClient, useQuery } from '@tanstack/react-query'; import React from 'react'; import { REACT_APP_API_KEY } from '~/config'; const fetchMovies = async (name: string) => { try { const response = await fetch( `https://api.themoviedb.org/3/search/movie?api_key=${REACT_APP_API_KEY}&language=en-US&query=${name}` ); if (!response) throw new Error(`Could not fetch movies -${name}`); return response.json(); } catch (error) { console.error(error); return []; } }; const Avengers = () => { const { data, status } = useQuery(['avengers'], () => fetchMovies('avengers')); if (status === 'loading') return <div>Loading...</div>; if (status === 'error') return <div>Error Occured!</div>; if (status === 'success' && !data) return <div>There is no data...</div>; return ( <> <div> <h1>Hello Avengers</h1> {data.results.map((item: any) => ( <div key={item.id}> <p> {item.title} - ({item.id}) </p> </div> ))} </div> </> ); }; export default Avengers; export async function getStaticProps() { const queryClient = new QueryClient(); await queryClient.prefetchQuery(['avengers'], () => fetchMovies('avengers')); return { props: { dehydratedState: dehydrate(queryClient) } }; }
'React.js & Next.js' 카테고리의 다른 글
빠르게 시작하는 드래그 앤 드롭 (0) 2023.03.26 Next Image load super slow (1) 2023.01.04 냅다 시작하는 리액트 쿼리 (개념편) (1) 2022.12.31 냅다 시작하는 리액트 쿼리 (예제편) (0) 2022.12.27 예제로 배우는 react context (0) 2022.12.18