Open2

Next.js細々TIPS

認証付きAPIでgetServerSidePropsを使う

  • useGameInfo: クライアントレンダリング用のAPI

    • 非公開モードに設定すると作成者しか閲覧できない(非ログイン時に404を返す)
  • game: SSRから渡されるprops

  • gameInfo: クライアントレンダリングで渡される情報

const Game = ({game}) => {
  const [gameInfo] = useGameInfo();
  return(
    <View>
    {gameInfo
      ?<GameView game={gameInfo}/>
      :<></>
    }
    {game
      ? 
        <MetaTags
          description={
            moment(game.game_date).format("YYYY/MM/DD") +
            " " +
            game.first_team_name +
            "-" +
            game.last_team_name +
            "のスコアブック"
          }
          title={
            moment(game.game_date).format("YYYY/MM/DD") +
            " " +
            game.first_team_name +
            "-" +
            game.last_team_name +
            "のスコアブック"
          }
        />
      :<></>
    }
    
      </View>
  )
}

export const getServerSideProps = async({params}) => {
  const response = await fetch(CAP_BACKEND + "/game/"+ params.game_id);
  if(response.status === 200){
    const game = await response.json();
    return{
      props:{
        game
      }
    }  
  }else{
    //responseが200以外なら空のpropsを返す
    return {
      props:{}
    }
  }
}

export default Game;

  • 場合分けをしないと404のレスポンスではNext.jsが500を返してしまう
  • Next10からはnotfound:trueで404ページを表示できるようになった
  • APIが404を返す時はメタタグも描画しない
  • firebaseログインを使って非公開モードでログイン時はCSRでページ自体の表示はできるようにする

getServerSidePropsでページ全体を描画すると重くなるので一部だけを返して残りはCSR

useSWRを使ってみる

SWRとは

SWRとは、Next.jsを作成しているVercel製のライブラリです。SWRはuseSWRというReact Hooksを提供し、APIを通じたデータの取得をラクに記述する手助けをしてくれます。
SWRは「stale-while-revalidate」の略

useSWRは第二引数で与えたfetcherが一度取得したデータをクライアント側でキャッシュしてくれます。

useSWRがキャッシュからデータを取得する流れは以下です。

  • キャッシュからデータを返そうとする(Stale)
  • キャッシュにデータがなければ、データを取得する
  • キャッシュにデータがあれば、再度データを取得してキャッシュを更新する(Revalidate)
    useSWRの第三引数にオプションとして指定することで、Revalidateを柔軟に設定できます。

実装

import useSWR from "swr";
const { data: info } = useSWR("fetchInfo", async () => await fetchInfo());
const { data: data } = useSWR(CAP_BACKEND + "/repute", async () => {
    const response = await fetch(CAP_BACKEND + "/repute");
      return await response.json();
  });

useSWRの第一引数はキャッシュするためのユニークなkey(URLをキーにするのが慣習)。
第二引数はfetcherと呼ばれるfetchするメソッドを渡す。
複数のAPIをuseSWRで投げる場合はdataを格納する変数を分ける。

SSRで使う

まだこの辺り実装試せてないです。

export async function getServerSideProps() {
  const data = await fetcher('/api/data')
  return { props: { data } }
}

function App (props) {
  const initialData = props.data
  const { data } = useSWR('/api/data', fetcher, { initialData })

  return <div>{data}</div>
}

参考リンク

https://zenn.dev/uttk/articles/b3bcbedbc1fd00
https://panda-program.com/posts/useswr
ログインするとコメントできます