← inaro.devAI駆動開発 学習ツール
応用

実践:AIのNext.jsコードをレビューする

なぜ学ぶか: Phase 03の総仕上げです。Next.js特有の観点で、AIが生成しがちな「動くけど危ない・遅い」コードをレビューします。下の例には問題が3つ隠れています。まず自分で探してみてください。

まずはこの例を見てみましょう

"use client";                                    // 【?】
import { useEffect, useState } from "react";

export default function Dashboard() {
  const [data, setData] = useState<string[]>([]);

  useEffect(() => {                                 // 【?】
    fetch("https://api.example.com/stats", {
      headers: {
        Authorization: process.env.NEXT_PUBLIC_API_SECRET,  // 【?】
      },
    })
      .then((res) => res.json())
      .then(setData);
  }, []);

  return <ul>{data.map((item) => <li key={item}>{item}</li>)}</ul>;
}

答え:①表示だけなら'use client'不要 ②初期データはサーバーで取る ③NEXT_PUBLIC_のシークレットは全世界公開(最重大)。

最優先は秘密の露出

例の③、NEXT_PUBLIC_付きのシークレットは誰でも見られます。他は「遅い・汚い」で済みますが、これだけは事故。最優先で直させます。

初期データはサーバーで

例の②、useEffectでの初期取得は古い書き方です。サーバーのコンポーネントで直接awaitすれば、速くシンプルになり、キーもサーバーに残せます。

'use client'は本当に必要か

例の①、表示するだけのページに操作機能はありません。サーバーのままにすれば軽くなります。

3つの問題は1つの直し方に集約

「サーバーのコンポーネントでデータを取る」に書き換えると、①②③が同時に解決します。構造の指摘は個別修正より強力です。

コード例

// ↓ 修正後の姿(3つの問題を一気に解決)
// 'use client' なし = サーバーで動く

export default async function Dashboard() {
  // 初期データはサーバーで直接取得
  const res = await fetch("https://api.example.com/stats", {
    cache: "no-store", // 統計は毎回最新を取得(作り置きしない)
    headers: {
      // 無印の環境変数 = サーバー専用。ブラウザには渡らない
      Authorization: `Bearer ${process.env.API_SECRET}`,
    },
  });
  if (!res.ok) throw new Error("取得に失敗しました");

  const data: string[] = await res.json();

  return <ul>{data.map((item) => <li key={item}>{item}</li>)}</ul>;
}

修正前(解説の例)と見比べてください。useState・useEffectが消え、キーはサーバーに残り、コードも短い。「サーバーで取る」だけで全部が良くなりました。

ステップ 1 / 2

※ カリキュラムの内容はAIが生成しており、誤りが含まれる場合があります。正確な情報は公式ドキュメント等でご確認ください。