-
(삽질금지 시리즈) Nextjs getServerSideProps에서 SSR 할때 react-query 사용 hydrate fetchQuery와 prefetchQueryNext.js 2024. 2. 2. 13:23728x90
개발 하면서 ssr를 이용하여 api를 요청 할때 try catch 구문을 이용하여 restapi의 error상태에 따라 error 페이지로 보내줄려고 했다.
ssr에서 react-query를 사용 할때 hydrate 방법을 사용 했는데, 굉장히 흥미로운게 있었다.
react-query를 ssr에서 사용 할때
const queryClient = new QueryClient();
await queryClient.fetchQuery
await queryClient.prefetchQuery이렇게 사용하는데
- fetchQuery
- perfetchQuery의 차이는
fetchQuery : 리턴값이 있다.
prefetchQeury: 리턴값이 없다.
fetchQuery : Promise<TData>
prefetchQeury: Promise<void>공식 문서의 예제에서는 prefetchQuery 메소드를 사용해서 데이터를 프리 패칭했다.
prefetchQuery 메소드는 데이터를 프리 패칭하고 캐시할 뿐, 어떠한 결과 값을 리턴하지 않는다.
반면에 fetchQuery 메소드는 데이터를 프리 패칭하고 캐시하고, 결과 값까지 리턴한다.따라서, 목적에 적합한 메소드를 선택해야 한다.
단순히 프리 패칭만 하면 되는 경우 prefetchQuery 를 사용하면 되겠다.
하지만, 서버 사이드 렌더링 시점에서 패치한 데이터의 값 자체를 사용해야 한다면 fetchQuery 를 사용한다.export const getServerSideProps = (async context => { const queryClient = new QueryClient(); const { scheduleId } = context.params as { scheduleId: string }; try { await queryClient.prefetchQuery<ScheduleItemResponse>( ['get-scheduleId', scheduleId], async () => { const { data } = await axiosAPI.get<ScheduleItemResponse>( `/groups/75aca3da-1dac-48ef-84b8-cdf1be8fe37d/schedules/75aca3da-1dac-48ef-84b8-cdf1be8fe37d`, ); return data; }, ); return { props: { dehydratedState: dehydrate(queryClient), }, }; } catch (e) { console.log('eee=', e); return { notFound: true, }; } }) satisfies GetServerSideProps;
나는 당연히 console.log('eee=', e); 부분이 실행이 되고 notFound 페이지로 넘겨줄줄 알았다.
social-frontend-1 | AxiosError: Request failed with status code 404
social-frontend-1 | at settle (file:///app/node_modules/axios/lib/core/settle.js:19:12)
social-frontend-1 | at IncomingMessage.handleStreamEnd (file:///app/node_modules/axios/lib/adapters/http.js:570:11)
social-frontend-1 | at IncomingMessage.emit (node:events:529:35)
social-frontend-1 | at endReadableNT (node:internal/streams/readable:1400:12)
social-frontend-1 | at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
social-frontend-1 | code: 'ERR_BAD_REQUEST',
social-frontend-1 | config: {
social-frontend-1 | transitional: {
social-frontend-1 | silentJSONParsing: true,
social-frontend-1 | forcedJSONParsing: true,
social-frontend-1 | clarifyTimeoutError: false
social-frontend-1 | },
social-frontend-1 | adapter: [ 'xhr', 'http' ],
social-frontend-1 | transformRequest: [ [Function: transformRequest] ],
social-frontend-1 | transformResponse: [ [Function: transformResponse] ],
social-frontend-1 | timeout: 0,
social-frontend-1 | xsrfCookieName: 'XSRF-TOKEN',
social-frontend-1 | xsrfHeaderName: 'X-XSRF-TOKEN',
social-frontend-1 | maxContentLength: -1,
social-frontend-1 | maxBodyLength: -1,
social-frontend-1 | env: { FormData: [Function], Blob: [class Blob] },
social-frontend-1 | validateStatus: [Function: validateStatus],갑자기 axios 에러가 떠버렸다.이게 뭔가 당연히 try 구문에서 에러가 발생했으니까 catch 구문으로 가야 되는거 아닌가?
export const getServerSideProps = (async context => { const queryClient = new QueryClient(); const { scheduleId } = context.params as { scheduleId: string }; try { await queryClient.fetchQuery<ScheduleItemResponse>( ['get-scheduleId', scheduleId], async () => { const { data } = await axiosAPI.get<ScheduleItemResponse>( `/groups/75aca3da-1dac-48ef-84b8-cdf1be8fe37d/schedules/75aca3da-1dac-48ef-84b8-cdf1be8fe37d`, ); return data; }, ); return { props: { dehydratedState: dehydrate(queryClient), }, }; } catch (e) { console.log('eee=', e); return { notFound: true, }; } }) satisfies GetServerSideProps;
웃긴건 fetchQuery 즉, 리턴값이 있으면 아주 정상적으로 catch 구문이 실행 되고 notFound 페이지로 보내준다.
문득 드는 생각은 아 내가 axios 에러처리를 무엇인가 잘못 했을 수 도 있겠다 싶었다.
728x90'Next.js' 카테고리의 다른 글
<w> [webpack.cache.PackFileCacheStrategy] (0) 2024.02.14 프론트에서 restapi를 이용한 http 통신을 할때 4xx번대 에러 또는 500번대에서 network 오류가 발생 했을때 크롬의 network 오류 표시 (0) 2024.02.03 (삽질금지 시리즈) Docker 환경에서 NextJS SSR 사용시 주의할점 (0) 2024.02.01 error (0) 2024.02.01 Image with src "blob:http://localhost:3000/975144f6-cd78-46cf-9cf8-b1addaf2b699" has legacy prop "layout". Did you forget to run the codemod? (0) 2023.10.18