Next js_getInitialProps

Daye Kang·2020년 2월 16일
0

Next js에서 데이터를 가져오기 위해서는 'getInitialProps'라 불리는 비동기 함수를 이용한다. async 함수로 'pages' 폴더 아래 어떤 페이지에서든 'static method'처럼 이용할 수 있다.

import fetch from 'isomorphic-unfetch'

function Page({ stars }) {
  return <div>Next stars: {stars}</div>
}

Page.getInitialProps = async ctx => {
  const res = await fetch('https://api.github.com/repos/zeit/next.js')
  const json = await res.json()
  return { stars: json.stargazers_count }
}

export default Page

fetch를 통해 받아온 데이터를 'props'로 넘겨줄 수 있는데, 데이터는 서버로 돌릴 때만 받아올 수 있다. 클라이언트 라우팅 될 때는 데이터를 받아올 수 없다.

'getInitialProps'는 'context'라 불리는 객체 형태의 인자를 받아서 쓸 수 있는데, 다음과 같은 'properties'가 있다.

  • pathname : 현재 라우트 path, '/pages'로 접근 가능하다.
  • query : URL의 쿼리 스트링 부분
  • asPath : 브라우저에서 보이는 실제 path
  • req : HTTP 요청 객체(오직 서버에서만)
  • res : HTTP 응답 객체(오직 서버에서만)
  • err : 렌더링 하는 동안 에러가 생겼을 경우 뜨는 에러 객체

Q. 데이터를 모든 페이지에 전달하고 싶다면?


_document.js 와 _app.js 모두 전역이지만 app_js를 써야 하는 이유!
데이터를 fetch하려면 _app.js에서 데이터를 받아 props로 'pages' 폴더 아래 페이지들로 넘겨주어야 한다.

// index.js 
import React from "react";
import Head from "next/head";
import Link from "next/link";

const Home = () => (
  <div>
    <Head>
      <title>Home</title>
      <link rel="icon" href="/favicon.ico" />
    </Head>
    <a href="/homepage">A_Tag</a> /// a 태그는 서버로 '/homepage'에 연결
    <div></div>

    <Link href="/homepage"> /// Link 는 클라이언트로 '/homepage'에 연결
      <a>LinkTag</a>
    </Link>
    <div></div>
    <Link href="/about"> // Link 는 클라이언트로 '/about'에 연결
      <a>About</a>
    </Link>
  </div>
);

export default Home;

'index.js'의 브라우저 상

// _app.js
import HomePage from "./homepage";

function MyApp({ Component, pageProps }) {
  return [
    <>
      <div>app.js</div>
      <Component {...pageProps} /> /// component에 데이터를 props로 넘겨줌
    </>
  ];
}

MyApp.getInitialProps = async appContext => {
  const { ctx, Component } = appContext;
  let pageProps = {};

  if (Component.getInitialProps) {
    // Component page에 getInitialProps가 있다면
    console.log("If there is Component, this console must be showed up.");
    pageProps = await Component.getInitialProps(ctx); 
    // component의 getInitialProps의 ctx를 데이터로 넘김.
    console.log("pageProps: ", pageProps);
  } else {
    // Component page에 getInitialProps가 없다면 app.js 의 내용만을 받아감
    const res = await fetch("https://api.github.com/repos/zeit/next.js");
    const json = await res.json();
    pageProps.title = "pageProps from My App";
    pageProps.number = json.stargazers_count;
    //pageProps 객체에 key-value 넣어줌.
  }
  return { pageProps };
};
export default MyApp;
// homepage.js
import fetch from "isomorphic-unfetch";
import { useEffect } from "react";

function HomePage(props) {

  useEffect(() => {
    console.log("ComponentDidMount");
  }, []);
  return ( // 브라우저에 렌더링 되는 부분
    <div>
      <div>Rendering from {props.from}</div>
      <div>Next stars: {props.stars}</div>
    </div>
  );
}

HomePage.getInitialProps = async ctx => { 
  console.log("HomePage.getInitialProps");
  let obj = { from: "server" };
  console.log("ctx.pathname: ", ctx.pathname);
  if (!ctx.req) {
    console.log("client side executed");
    obj.from = "client";
  }
  const res = await fetch("https://api.github.com/repos/zeit/next.js");
  const json = await res.json();
  return { stars: json.stargazers_count, ...obj };
};

export default HomePage;
profile
뭐든 하자

0개의 댓글