티스토리 뷰

반응형

목록

Fetching Data for Pages

지금까지 next.js의 routing API를 활용하는 방법에 대해 배웠습니다. 이것만으로도 꽤 괜찮은 앱을 만들 수 있지만, 실제로 서비스 되는 앱들은 보통 데이터를 가지고 와서 앱에 뿌려주어야 합니다. Next.js에는 데이터를 가지고 오는 표준 API가 제공됩니다. 우리는 비동기 함수인 'getInitialProps'를 사용할 것입니다.


이를 통해 데이터를 가지고 올 수 있고 props를 통해 우리의 페이지에 전달 할 수 있습니다. getInitialProps를 사용함으로써 서버와 클라이언트에서 모두 작동하게 할 수 있습니다. 


이번 장에서는 getInitialProps를 사용해  TVmaze API에서 배트맨 tv show의 정보를 가지고 와서 앱을 만들어 보겠습니다.


Setup

아래의 예제를 다운로드 해주세요
git clone https://github.com/zeit/next-learn-demo.git
cd next-learn-demo
cd 6-fetching-data

npm install
npm run dev


Fetching Batman Shows

현재 데모 앱에는 블로그 포스트 리스트가 있습니다. 지금부터 할 것은 batman TV shows 리스트를 보여줄 것입니다. 하드코딩하지 않고 원격 서버로 부터 데이터를 가지고 와서 만들겠습니다.

TV show를 검색하는 API인 TVMaze API 를 사용해서 데이터를 가지고 올 것입니다.


먼저 우리는 isomorphic-unfetch 를 설지해야 합니다. 데이터를 가지고 올 때 사용할 라이브러리 입니다. 브라우저의 fetch API를 간단하게 구현한 것이지만 클라이언트와 서버에서 모두 작동합니다.


npm install --save isomorphic-unfetch


'pages/index.js'에 아래의 코드를 입력하세요


import fetch from 'isomorphic-unfetch'

const Index = props => (
  <Layout>
    <h1>Batman TV Shows</h1>
    <ul>
      {props.shows.map(show => (
        <li key={show.id}>
          <Link href="/p/[id]" as={`/p/${show.id}`}>
            <a>{show.name}</a>
          </Link>
        </li>
      ))}
    </ul>
  </Layout>
)

Index.getInitialProps = async function() {
  const res = await fetch('https://api.tvmaze.com/search/shows?q=batman')
  const data = await res.json()

  console.log(`Show data fetched. Count: ${data.length}`)

  return {
    shows: data.map(entry => entry.show)
  }
}

export default Index


위의 페이지에서 Index.getInitialProps를 제외하고는 익숙한 내용일 것입니다. Index.getInitialProps를 살펴 봅시다


Index.getInitialProps = async function() {
  const res = await fetch('https://api.tvmaze.com/search/shows?q=batman')
  const data = await res.json()

  console.log(`Show data fetched. Count: ${data.length}`)

  return {
    shows: data.map(entry => entry.show)
  }
}


앱의 어느 페이지에나 추가할 수 있는 정적인 비동기 함수 입니다. 이를 사용해서 가지고 온 데이터를 페이지에 props로 넘겨줄 수 있습니다.

index페이지를 확인해 보면 show props로 가지고온 정보를 넘겨주어 화면에 리스트가 나오는 것을 확인 할 수 있습니다.


여기서 확인해야 할 것은 데이터를 서버에서 가지고 오는지 클라이언트에서 가지고 오는지 입니다. 새로 고침을 했을 때 getInitialProps 안에 있는 console.log의 내용이 어디에 찍히는지 보면 확인을 할 수 있습니다. 새로 고침을 할 경우 서버의 콘솔에서만 메세지가 출력되는 것을 볼 수 있습니다. 


Only on the Server

서버에서 이미 데이터를 가지고 왔기 때문에 클라이언트에서는 다시 데이터를 가지고 올 필요 없이 서버에서 가져온 데이터를 기반으로 페이지를 렌더합니다. 이는 초기 url로 접속시에는 서버사이드 렌더링이 되기 때문입니다. 브라우저 내부에서 페이지를 이동할 경우에는 클라이언트 사이드 렌더링이 되므로 브라우저의 개발자 도구 콘솔에 메세지가 나타날 것 입니다.


Implement the Post Page

이제 TV show의 상세한 정보를 보여주는 페이지를 추가합시다.
'pages/p/[id].js' 파일에 아래 내용을 코딩하세요


import Layout from '../../components/MyLayout'
import fetch from 'isomorphic-unfetch'

const Post = props => (
  <Layout>
    <h1>{props.show.name}</h1>
    <p>{props.show.summary.replace(/<[/]?p>/g'')}</p>
    <img src={props.show.image.medium} />
  </Layout>
)

Post.getInitialProps = async function(context) {
  const { id } = context.query
  const res = await fetch(`https://api.tvmaze.com/shows/${id}`)
  const show = await res.json()

  console.log(`Fetched show: ${show.name}`)

  return { show }
}

export default Post


이 페이지의 getInitialProps를 살펴 봅시다


Post.getInitialProps = async function(context) {
  const { id } = context.query
  const res = await fetch(`https://api.tvmaze.com/shows/${id}`)
  const show = await res.json()

  console.log(`Fetched show: ${show.name}`)

  return { show }
}


첫 번째 인수로 context객체를 넣었습니다. 'query'객체를 fetch 에서 사용할 수 있습니다.


예를 들면 query에서 show ID를 선택해서 TVMaze API의 show 데이터를 가지고 올 수 있습니다.


Fetch Data in Client Side

서버와 브라우저 콘솔을 모두 열고 이번에는 콘솔 메세지가 어디에 나타나는지 확인해 봅시다. index페이지에 생성된 링크를 클릭 했을 때 브라우저의 콘솔 창에 콘솔 메세지가 나타나는 것을 확인 할 수 있습니다. 위에서 설명 했듯이 브라우저 내부에서의 이동은 클라이언트 사이드 렌더링이 됩니다.

이는 Next.js의 <Link /> 컴포넌트로 랩핑된 링크를 클릭 할 경우에 가능합니다. http : // localhost : 3000 / p / 975 페이지를 직접 방문할 경우에는 url로 초기 접속을 했기 때문에 서버사이드 렌더링이 되면서 서버의 콘솔에 콘솔 메세지가 출력 되는 것을 볼 수 있습니다.

 Finally

지금까지 Next.js에서 가장 중요한 기능 중 하나인 서버사이드 렌더링과 데이터를 가지고 오는 방법에 대해 배웠습니다. 기본적인 방법만 배웠지만 대부분의 경우 문제가 없을 것 입니다. 더 자세히 알고 싶다면 Next.js document의 data fetching 를 확인 하세요




Next js 튜토리얼 5편 : 동적 라우팅  

Next js 튜토리얼 6편 : 데이터 가져오기  - 현재 글

Next js 튜토리얼 7편 : 컴포넌트 스타일링  

Next js 튜토리얼 8편 : 배포

반응형
댓글