Notice
Recent Posts
Recent Comments
관리 메뉴

즐겁게, 코드

서버 데이터를 속성으로 활용하기 본문

🎨 프론트엔드/Next.js

서버 데이터를 속성으로 활용하기

Chamming2 2021. 2. 22. 16:05

넥스트(Next.js)는 기본적으로 모든 페이지를 미리 렌더링합니다.

미리 렌더링을 해두면 SEO에도 유리하고 더 나은 성능을 얻을 수 있는데요, 넥스트에는 두 가지 사전 렌더링 방법이 존재합니다.

 

1. 정적 생성 - HTML 페이지를 미리 렌더링해두고 요청에 따라 제공합니다.

2. 서버 사이드 렌더링 - 페이지가 요청되는 시점에 서버에서 렌더링을 수행하고 결과물을 제공합니다.

 

별도의 외부 데이터가 필요하지 않다면 정적 생성 방식으로 미리 렌더링된 페이지를 제공합니다.

그러나 외부 데이터를 필요로 하는 경우에는 서버 사이드 렌더링을 통해 페이지를 제공하는데요, 오늘은 넥스트에서 어떻게 외부 데이터를 다룰 수 있는지 알아보도록 하겠습니다.

getServerSideProps

getServerSideProps는 넥스트에서 제공하는 기본 API로, 외부 데이터를 요청한 후 이를 컴포넌트의 속성(props)로 전달합니다.

import axios from "axios";

export default function index({ user }) {
  // 데이터를 불러오지 못했을 시 userName에는 undefined가 저장됩니다.
  const userName = user && user.name;
  return (
    <div>
      <div>{userName}</div>
    </div>
  );
}

// getServerSideProps는 페이지 요청 시마다 호출되며, 별도의 임포트 없이 사용할 수 있습니다.
export const getServerSideProps = async () => {
  try {
    const res = await axios.get("https://api.github.com/users/c17an");

    if (res.status === 200) {
      const user = res.data;
      return { props: { user } };
    }
    return { props: {} };
  } catch (error) {
    console.log(error);
    return { props: {} };
  }
};

getServerSideProps는 페이지 요청 시 자동으로 호출되며 비동기 요청으로 불러온 외부 데이터를 컴포넌트 속성으로 전달할 수 있습니다.

이제 이를 응용해 검색창에 아이디를 입력하면 유저 정보를 출력하는 페이지를 만들어 보겠습니다.

index.jsx

import axios from "axios";
import { useState } from "react";
import Link from "next/Link";

export default function index() {
  const [userName, setUserName] = useState("");

  const handleOnChange = (e) => {
    setUserName(e.target.value);
  };

  return (
    <div>
      <label htmlFor="input">유저 아이디 : </label>
      <input
        id="input"
        type="text"
        value={userName}
        onChange={handleOnChange}
      />
      <div>
        <Link href={`/user/${userName}`}>
          <a>유저 검색하기</a>
        </Link>
      </div>
    </div>
  );
}

/user/[user].jsx

import axios from "axios";

const user = ({ user }) => {
  const userName = user && user.name;
  return (
    <div>
      <div>유저 이름 :</div>
      <div>{userName}</div>
    </div>
  );
};

// getServerSideProps는 해당 페이지의 쿼리 객체를 인자로 가집니다. 
export const getServerSideProps = async ({ query }) => {
  // 이 페이지의 파일명은 [user].jsx 이므로 쿼리 객체는 {user: "쿼리 인자명"} 이 됩니다.
  const { user } = query;
  try {
    const res = await axios.get(`https://api.github.com/users/${user}`);
    if (res.status === 200) {
      const user = res.data;
      return {
        props: { user },
      };
    }
  } catch (err) {
    console.log(err);
    return {
      props: {},
    };
  }
};

export default user;

https://api.github.com/users/유저명 을 통해 깃허브 api를 활용할 수 있습니다.

getStaticProps

외부 데이터를 활용하는 대신 빌드 시에 정적인 데이터를 불러오는 방법도 존재합니다.

getStaticProps 는 빌드 시에 데이터를 불러온 후 결과를 json으로 저장해 일관적인 데이터를 보여주게 됩니다.

const staticPage = ({ time }) => {
  return <div>{time}</div>;
};

export const getStaticProps = async () => {
  return { props: { time: new Date().toLocaleString() } };
};

export default staticPage;

npm run build 로 페이지를 빌드한 후, npm start 로 페이지를 실행해 보세요.

getStaticProps를 사용하면 빌드 시점의 데이터가 속성으로 전달되기 때문에, 새로고침을 해도 데이터가 변하지 않습니다.

다만 revalidate 옵션을 통해 특정 주기마다 데이터를 갱신하도록 할 수도 있습니다.

const staticPage = ({ time }) => {
  return <div>{time}</div>;
};

export const getStaticProps = async () => {
  // 5초마다 새로고침 시 시간이 갱신됩니다.
  return { props: { time: new Date().toLocaleString() }, revalidate: 5 };
};

export default staticPage;

TL;DR

- 서버로부터 페칭한 값을 속성(props)으로 사용하고자 할때는 getServerSideProps API를 활용한다.

- 빌드 시의 정적인 값을 속성으로 사용하고자 할때는 getStaticProps API를 활용한다.

반응형
Comments
소소한 팁 : 광고를 눌러주시면, 제가 뮤지컬을 마음껏 보러다닐 수 있어요!
와!! 바로 눌러야겠네요! 😆