Next.jsでのダイナミックルーティング router.queryで取得したIDと同じIDのdocsをfirestoreから取得して表示させたい

前回までの作業でseRouterのrouter.queryを使ったダイナミックルーティングは出来るようになりました。(できるようになった理由は理解できていないけどね!!!!!!!)

こんな感じで、URLのクエリの文字列をページ上でレンダリングできるようになりました。ちなみにコードは以下です。

import { useRouter } from "next/router";
import React from "react";
const Page = () => {
  const router = useRouter();
  const id = router.query;
  console.log(id.test2);
  if (!router.isReady) {
    return null;
  }
  return <p>hello! id: {id.test2}</p>;
};
export default Page;

上記のコードを書くにあたって参考にさせていただいたのはこちらの記事。

routerのisReadyプロパティを使うことで、idがundefinedになることを防いで、レンダリングできるようになりました。

これを使えば、今作っているTodoアプリの詳細ページを動的に生成できるので嬉しいです。

そして次にやりたいのは、Todoの詳細ページの中身の生成です。

今作っているTodoアプリはfirestoreを使っていて、データはすべてfirestoreのdocに格納されています。なのでfirestoreのgetメソッドを使ってデータを取得したいのですが、どのデータを取得するかを指定するのに、今回ダイナミックルーティングに使っているrouter.queryをそのまま使いたいんですよね。

そこでこんな感じで書いてみました。

import { useRouter } from "next/router";
import { db } from "../../firebase";
import React from "react";

const Page = async () => {
  const router = useRouter();
  const id = router.query;
  console.log(id.test2);
  if (!router.isReady) {
    return null;
  }
  const TodoData = await db
    .collection("tasks")
    .doc("{id.test2}")
    .get()
    .then((snapshot) => {
      console.log(snapshot.data());
      return (
        <>
        <h1>Blog post</h1>
        <p>Post id: {id.test2}</p>
        </>
        );
    });
};

export default Page;

ですが以下のようなエラーが出てしまいました。

このエラーを翻訳してみると

エラー:オブジェクトはReactの子として有効ではありません(見つかった:[object Promise])。子のコレクションをレンダリングする場合は、代わりに配列を使用してください。

とのことです。最初はまったく意味がわかりませんでしたが、ちょっと調べてみると「asyncを使うと、Promise オブジェクトが返ってくるらしい」ということがわかりました。それはこの記事を見ていて気づきました。

なるほど・・・まそもそもね?Promiseもasync awaitもね、正直雰囲気で使っていまして。というかPromiseに関してはハジメマシテじゃないです?前にどこかでお会いした記憶はないんだよね。

ということでPromiseやasync awaitのあたりのインプットをしてみるところから始めたいと思います。

先は長そうですけど、こういう気付きが1日1個でもあるなら良しとしようと思います。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です