반응형
카엔입니다
카엔
카엔입니다
전체 방문자
오늘
어제
  • 분류 전체보기 (98)
    • 프론트엔드 (74)
      • JavaScript (22)
      • CSS (2)
      • React (21)
      • Next.js (12)
      • 블록체인 (2)
    • 에러 모음 (11)
    • Git (5)
    • 백엔드 (1)
      • GraphQL (1)
    • AWS (2)
    • CS (1)
    • 코딩테스트 (1)
    • 개발 이야기 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 모바일 파란 박스
  • unoptimized error
  • nextron
  • error
  • 이벤트루프
  • git 덮어쓰기
  • ec2
  • ChatGPT
  • 자바스크립트 이진수 변환
  • 구글 스프레드시트 API
  • ipc 통신
  • 자릿수 채우기
  • Next.js
  • git
  • useMemo
  • DOUBLE CHECK CONFIGURATION Please double check that you have setup a PAID OpenAI API Account. You can read more here: https://docs.agpt.co/setup/#getting-an-api-key
  • useCallback
  • Cloudfront
  • nextron ipc
  • 웹상동작과정

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
카엔입니다

카엔

Next.js ISR와 React Query 연동
프론트엔드/Next.js

Next.js ISR와 React Query 연동

2023. 5. 10. 12:41

Next.js에서 ISR과 React Query를 연동하는 방법에 대해서 알아보려합니다

그전에 우선 렌더링 방식에 대한 간단한 설명부터 하겠습니다

렌더링 방식

CSR(Client Side Rendering)

웹페이지의 내용을 클라이언트에서 렌더링하는 방식임

렌더링의 책임을 사용자에게 전가하는 것

화면 로딩이 사용자 눈에 보여서 사용자 경험을 감소시키는 단점이 있음

SSR(Server Side Rendering)

웹페이지의 내용을 서버 측에서 렌더링한 후 완성된 HTML 파일을 클라이언트에 전달함

프론트엔드 서버에게 렌더링의 책임을 전가하는 것

사용자가 웹에 접속할때마다 새로운 페이지를 생성해줌

항상 최신 정보를 유지해야한다면 좋은 방식

페이지가 즉시 보이지만 서버가 부하를 감당해야한다는 단점이 있음

근데 성능상 이슈가 있으며 화면깜빡임 현상이 있음

SSG(Static Site Generation)

Build Time HTML 데이터를 받아서 → 미리 파일을 만들고 → 이걸 접속한 사용자에게 보여주는 방식

즉, 빌드 타임에 웹페이지를 미리 렌더링하여 정적 파일로 생성하는 방식입니다

이미 만들어진 페이지를 여러 사람들에게 보여주는거라 서버부담이 적고 응답속도가 빠릅니다

빠른 로딩 속도와 SEO 향상도 가져갈수 있습니다

하지만 매 페이지마다 빌드를 수행하기 때문에 마케팅 페이지 블로그 글 등 한번 만들면 변화가 별로 없는거에 사용됨

getStaticProps() 메소드를 사용해 데이터를 불러오고, 이를 페이지 컴포넌트의 props로 전달해주면 됩니다

그러므로 API와 같은 요청은 빌드 타이밍에서 처리해줘야합니다

ISR(incremental Static Regeneration)

정적생성으로 만들어놓은 페이지이지만 업데이트가 가능한 방식

정적생성의 장점 + 단점 보완한 방식으로 SSG에서 간단한 옵션 추가로 사용가능

빌드시점에 페이지 생성(SSG와 동일)

일정 시간 지난 후 페이지 새로 생성

최신 버전의 페이지를 비동기적으로 생성함

아래는 공식문서에서 제공하는 가이드입니다

function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// the path has not been generated.
export async function getStaticPaths() {
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // Get the paths we want to pre-render based on posts
  const paths = posts.map((post) => ({
    params: { id: post.id },
  }))

  // We'll pre-render only these paths at build time.
  // { fallback: blocking } will server-render pages
  // on-demand if the path doesn't exist.
  return { paths, fallback: 'blocking' }
}

// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// revalidation is enabled and a new request comes in
export async function getStaticProps() {
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  return {
    props: {
      posts,
    },
    // Next.js will attempt to re-generate the page:
    // - When a request comes in
    // - At most once every 10 seconds
    revalidate: 10, // In seconds
  }
}

export default Blog

데이터 페칭

  • getStaticPath
    • 유저의 요청마다 fetch할 필요가 없는 고정된 내용의 페이지를 렌더링할때 사용됨
  • getStaticProps
    • 어떤 페이지를 미리 static으로 빌드할지 정하는 api, 동적 라우팅할 떄 적합함
  • getServerSideProps
    • 자주 변경되는 페이지를 렌더링할때 사용된다
    • fetch해야할 데이터가 있을때 사용한다
    • 서버에 부담을 주기 때문에 꼭 필요한 곳에서만 사용한다

Tanstack-Query

위에서 ISR를 적용하는 방식에 대해 설명했는데, 이번에는 React-Query를 사용해서 ISR과 연동하는 방법에 대해 알아보려합니다

먼저 React-query는 Tanstack-Query로 명칭이 변경됬습니다

아래는 추천하는 방식인 Dehydration 방식으로 ISR를 적용하는 방법입니다

initialData 방법이 세팅수요도 적고 간단하나 자손 컴포넌트까지 data를 props drilling 해야한다는 번거로움이 존재하고,

Hydration 방법은 queryClient로 간단히 접근 가능하며 기존 queryKey 값을 활용할 수 있다는 장점이 있어 2번을 권장하는 것이다.

여기서 hydration은 pre-rendering과 관련이 있다 각 페이지의 HTML을 미리 생성하고 생성된 HTML은 해당 페이지에 필요한 자바스크립트 코드와 연결하고 브라우저에 의해 페이지가 로드되면 자바스크립트 코드가 실행되어 유저와 인터랙트할 수 있는 방법이다 hydration은 두가지로 나뉘는데 SSG와 SSR로 나뉘게 된다

Dehydration

공식문서

Overview | TanStack Query Docs

우선 hydartion에 개념부터 알아보자면

SSR에서 정적인 페이지(HTML)를 렌더링하고

→ JS가 모두 로드되면 HTML에 이벤트 핸들러를 붙혀

→ 동적인 페이지를 만드는 과정 자체를 hydration이라고 말합니다

dehydrate는 나중에 hydrate로 공급할 수 있는 cache에 대한 고정된 표현을 생성하며, hydrate는 이전에 dehydrate된 state를 cache에 추가합니다

또한 React-query는 Next.js 서버에서 여러 개의 query를 prefetch하고 그 query들을 queryClient에 dehydrate하는 것을 지원합니다

서버는 페이지 로드시 즉시 사용할 수 있는 마크업을 미리 렌더링하는 것을 뜻합니다

InitialData

initialData로 넘겨주게되면 빠른 설정이 가능하지만 props drilling 등 몇가지 문제가 생기게 된다

같은 query가 여러 곳에서 호출된다면 모두 initialData를 세팅해야한다

query가 서버에서 fetch된 정확한 시점을 모르기에 페이지가 로드된 시점을 기준으로 dataUpdatedAt을 설정해서 refetch가 된다

export async function getStaticProps() {
	const posts = await getPosts()  
	return { props: { posts } }
}

function Posts(props) {  
	const { data } = useQuery(['posts'], getPosts, { initialData: props.posts })
  // ...
}

Hydration

getStaticProps, getServerSideProps 함수에서 prefetch를 통해 쿼리 데이터를 미리 요청한다

그리고 결과값이 담긴 queryClient를 dehydrate한 뒤 page.props에 dehydratedState로 내려주는 방법이 있다

// _app.jsx
import { Hydrate, QueryClient, QueryClientProvider } from 'react-query'
 
export default function MyApp({ Component, pageProps }) {
   const [queryClient] = React.useState(() => new QueryClient())
 
   return (
     <QueryClientProvider client={queryClient}>
       <Hydrate state={pageProps.dehydratedState}>
         <Component {...pageProps} />
       </Hydrate>
     </QueryClientProvider>
   )
}

hydration시 참조를 위한 pageProps.dehydratedState를 넘겨준다

queryClient는 lifeCycle 주기당 인스턴스가 1번만 생성되도록 App 외부, state, 혹은 ref 등으로 저장한다

// /components/Component.jsx

// pages/posts.jsx
import { dehydrate, QueryClient, useQuery } from '@tanstack/react-query';

export async function getStaticProps() {
  const queryClient = new QueryClient()

  await queryClient.prefetchQuery(['posts'], getPosts)

  return {
    props: {
      dehydratedState: dehydrate(queryClient),
    },
  }
}

function Component() {
  const { data } = useQuery(['posts'], getPosts)
}

queryClient 인스턴스를 생성한 뒤 여기에 prefetchQuery 메소드로 쿼리를 refetch 한다

query를 캐싱하기 위해 dehydrate 처리를 한 queryClient를 dehydratedState로 추가한다


참조

https://abangpa1ace.tistory.com/267

 

[React Query] (5) SSR

🧐 서론 지난 포스팅까지 진행하며, React Query를 사용해서 데이터를 다루는 주요 문법들을 정리하였다. 프로젝트를 마이그레이션하며 적용하던 중, Next.js 세팅인 점을 상기했으며 당연히 React Que

abangpa1ace.tistory.com

https://www.howdy-mj.me/next/hydrate

 

Next.js의 렌더링 과정(Hydrate) 알아보기

누군가 나에게 Next.js를 쓰는 이유를 물어본다면, 가장 먼저 SSR 때문이라고 대답할 것 같다. Next.js 공식 홈페이지에서도 가장 먼저 강조하고 있는 것이 'hybrid static & server rendering'인 것처럼 말이다

www.howdy-mj.me

https://velog.io/@te-ing/Next.js%EC%9D%98-%EB%8D%B0%EC%9D%B4%ED%84%B0%ED%8C%A8%EC%B9%AD-%EB%B0%A9%EC%8B%9D-getStaticProps-getStaticPath-getServerSideProps%EC%9D%80-%EC%96%B8%EC%A0%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94%EA%B0%80

저작자표시 (새창열림)

'프론트엔드 > Next.js' 카테고리의 다른 글

Next.js build시 Image Optimization 설정 에러  (0) 2023.05.16
Nextron(eletron) IPC 통신  (0) 2023.05.08
Next.js SSG에 대해서 알아보자  (0) 2023.04.26
Next.js에서 미디어쿼리 (반응형) 적용하기  (0) 2023.04.19
Next/image가 외부 이미지를 import 해오지 못하는 문제  (0) 2022.12.29
    '프론트엔드/Next.js' 카테고리의 다른 글
    • Next.js build시 Image Optimization 설정 에러
    • Nextron(eletron) IPC 통신
    • Next.js SSG에 대해서 알아보자
    • Next.js에서 미디어쿼리 (반응형) 적용하기
    카엔입니다
    카엔입니다
    https://www.kaen.site/

    티스토리툴바