kanioka
@kanioka (優士 谷岡)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

getServerSidePropsの値が取得できない(undefinedになる)

解決方法

_app.tsxの書き方を修正する。

function MyApp({ Component, pageProps }: AppProps) {
  return (
-     <Component />
+     <Component {...pageProps}/>
  );
}

単純なミスでしたorz

解決したいこと

getServerSidePropsの値を取得、表示したい。
特殊な書き方をしていないと思うのですが、
getServerSidePropsの値が取得できません。
公式の書き方や検索したら出てくる解消法を一通り試しましたが
ダメでした。。。

Next.jsの設定はプロジェクトを作成して
ほとんど変更はしていません。

バージョン

next.js : 12.2.0
react : 18.2.0
typescript : 4.7.4

※Next.js, React, TypeScript初心者です。
言葉の使い方や言い回しが不適切な場合は
ご指摘いただければ幸いです。

クライアント側

pages/admin/edit
import type { GetServerSideProps, InferGetServerSidePropsType } from "next";
import * as React from "react";

type Props = InferGetServerSidePropsType<typeof getServerSideProps>;

const Edit = (data: Props) => {
  console.log(data); // undefined
  return <></>;
};
export const getServerSideProps: GetServerSideProps = async (context) => {
  const url = `http://localhost:3000/api/admin/get`;
  const res = await fetch(url, {
    headers: {
      "Content-Type": "application/json;charset=utf-8",
    },
  });
  const data = await res.json();
  console.log({ data }); // ← array object
  return {
    props: {
      data,
    },
  };
};
export default Edit;

サーバー側

pages/api/get
import type { NextApiRequest, NextApiResponse } from "next";

import { sequelize } from "../../../libs/db";
export default async (req: NextApiRequest, res: NextApiResponse) => {
  const id = req.query.id;
  await sequelize.sync();
  const sql = `
  SELECT * FROM admin
  WHERE id = 1
  `;
  const query = await sequelize.query(sql);
  const result = await typeof query !== undefined ? query[0] : [];
  /** 下記の形で取得
  [
    {
    id:1,
    name:'test
  }
]
   */
  res.status(200).send(JSON.stringify(result));
};

自分で試したこと

公式+下記サイトのような書き方
https://stackoverflow.com/questions/61314910/props-passed-to-page-from-getserversideprops-is-always-undefined
https://stackoverflow.com/questions/70962619/why-is-my-getserversideprops-coming-back-as-undefined-within-my-nextjs-app-i-am

0

4Answer

Screen Shot 2022-08-01 at 9.34.59.png

なにか自分的に難しいと思うことをする場合は、まずは静的なデータを元にデータが流れていくことを確認してから、徐々に動的になる部分を増やしていくと理解が早い気がします。

import type { GetServerSideProps } from "next";
import React from 'react';
interface Props{
  data: number[]
}

const Edit: React.FC<Props> = ({data}) => {
  console.log('data:', data)

  return (
    <>
      test
    </>
  )
}
export default Edit

export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
  return {
    props: {
      data: [1, 2, 3],
    },
  };
};

GetServerSidePropsは下のような定義になっているので、propsの型はComponent Function側で受け取りたい形をGetServerSidePropsのGenericsとして渡したほうが流れ的には良いと思います。

export type GetServerSidePropsResult<P> =
  | { props: P | Promise<P> }
  | { redirect: Redirect }
  | { notFound: true }

export type GetServerSideProps<
  P extends { [key: string]: any } = { [key: string]: any },
  Q extends ParsedUrlQuery = ParsedUrlQuery,
  D extends PreviewData = PreviewData
> = (
  context: GetServerSidePropsContext<Q, D>
) => Promise<GetServerSidePropsResult<P>>

あと、気になったのはpages/api/getを作ってて、それを更にGetServerSideProps側から呼んでることです。
pages/api/getは一般公開のURLになってしまうので、最悪誰でも呼べます。

このEditページだけでpages/api/get内でやってるようなSQL処理が必要なら、単純にGetServerSidePropsにpages/api/get内のコードをごっそり持ってくれば良いだけな気もします。
複数箇所で呼ばれるにしても、別関数として切り出してimportするほうが楽な気もします。

0Like

Comments

  1. @kanioka

    Questioner

    ご回答ありがとうございます。
    ご記載いただいたコードで確認すると
    「data: undefined」になってしまします。。。

    GetServerSidePropsのpropsや
    page/api/getについての
    ご指摘ありがとうございます。
    勉強になります!!!

    とりあえず動けば良いと作ってしまっていて、
    ディレクトリまで意識できていませんでした。

    本件に関しては1~2日くらい引き続き調査してみて、
    難しそうならプロジェクトを作り直してみます。
  2. > 「data: undefined」になってしまします。。。

    そんなはずはないですが... スクリーンショットのようにクライアント側にデータが来ているのも確認していますし。
    そもそもnext.jsのバージョンは何ですか?
  3. @kanioka

    Questioner

    @github0013@githubさんのコードが正しいのは理解しています。
    頂いたコードはもちろん、
    公式の書き方や、記事で動いているであろう
    コードはいくつも試しましたがどれもundefindedになる状況です。

    >そもそもnext.jsのバージョンは何ですか?
    next.jsのバージョンは12.2.0になります。

  4. @kanioka

    Questioner

    返事が遅くなり申し訳ございません。
    _app.tsxを掲載しました。
  const query = await sequelize.query(sql);]]
  const result = await typeof query !== undefined ? query[0] : [];

ここは誤記ではないです?
使用しているライブラリと照らし合わせてちゃんとresultに期待するものが入るかどうか確かめてみるのが先だと思われます.

0Like

Comments

  1. @kanioka

    Questioner

    ご回答ありがとうございます。
    修正しました。
    質問用に修正している途中に誤記が入ってしまいました。

そもそもがgetServerSidePropsが呼ばれていない可能性も考えてそちらにデバッグを入れてみるといいでしょう.
サーバはnext startから起動したうえで確実にhttp://localhost:3000/admin/editにアクセスしていますか?
その辺りの手順を詳細に記述すると何か分かるかもしれません.

0Like

Comments

  1. @kanioka

    Questioner

    返事が遅くなり申し訳ありません。

    デバッグを行いgetServerSidePropsは呼ばれてました。
    getServerSideProps内では値は取得できています。

    next start ではなくnext devで行っていましたが、
    確実にhttp://localhost:3000/admin/editにアクセスしています。

    next start で試してみます!

Comments

  1. @kanioka

    Questioner

    回答遅れました。

    動作しました😢
    大変勉強になりました!!
    ありがとうございます!

    一番肝心な箇所を見逃していました、、、、

Your answer might help someone💌