🍇

【Next.js】SSRを勉強する!

2022/08/20に公開

https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props

上記ドキュメントをベースにSSRについて勉強していきたいと思います。
初心者なので、色々ツッコミもらえたら嬉しいです。

以下に自分なりに理解したことを書いていきたいと思います。

SSRはgetServerSidePropsを利用して実現します。

getServerSidePropsをpageでexportすることにより、

クライアント(ブラウザ)がサーバーに対してページを要求した際に、その都度getServerSidePropsが

データを取得し、そのデータをpropsとしてpageに渡し、レンダリングを行い、

完成されたHTMLファイルをクライアントに返すことができます。

SSGはビルド時にデータを取得し、静的ファイルを生成し、リクエストがあったらそのファイルをレスポンスとして返しているので、最新のデータを取得したい場合などはSSRの方が適しています。
色々レンダリング手法はありますが、それぞれメリットデメリットがあるので、用途によって使い分ける必要があります。

実際にやってみる

まずはAPIからデータを取得しないで、getServerSidePropsを使って、挙動を見ていきます。

tweet/index.js
import React from "react";

const index = ({ item }) => {
  console.log(item);
  return <div>{item}</div>;
};

export default index;

export const getServerSideProps = async () => {
//以下のconsole.logはブラウザで実行されない
  console.log("hello next.js");
  return {
    props: {
      item: "hello world",
    },
  };
};

http://localhost:3000/tweet にアクセスするとサーバーでまずgetServerSidePropsが実行されます。つまりgetServerSideProps内のconsole.logはブラウザの開発者ツールには表示されず、サーバー側のログに表示されます。

return

return {
    props: {
      item: "hello world",
    },
  };

上記のようにすることで、コンポーネントはpropsを受け取ることができます。つまりgetServerSideProps内でAPIを叩いてデータを取得し、コンポーネントにpropsとしてデータを渡して、レンダリングするという流れが基本となります。

https://nextjs.org/docs/api-reference/data-fetching/get-server-side-props
今回return に propsを指定しましたが、他にもnotFoundredirectを指定することが可能です。

contextパラメータ

export const getServerSideProps = async (context) => {

上記のようにgetServerSidePropsは引数にcontextパラメータを指定することで、getServerSideProps内のロジックで使用できるような情報を取得することができます。
contextはオブジェクトで様々なキーを持ちます。
例えば
http://localhost:3000/tweet?id=100 として

console.log(context.query);

とすれば、以下のようなオブジェクトを取得することができます。

{ id: '100' }

API叩いて画面に表示する簡単なExample

import { gql } from "@apollo/client";
import React from "react";
import { client } from "../_app";

const index = ({
  tweets: {
    data: { tweets },
  },
}) => {
  return (
    <div>
      {tweets.map((tweet) => {
        return <div key={tweet.id}>{tweet.content}</div>;
      })}
    </div>
  );
};

export default index;

export const getServerSideProps = async () => {
  const tweets = await client.query({
    query: gql`
      query {
        tweets {
          id
          content
        }
      }
    `,
    fetchPolicy: "network-only",
  });
  return {
    props: {
      tweets,
    },
  };
};

Discussion