y-u27 / your-todo-by-Next.js

https://your-todo-by-next-js.vercel.app
0 stars 0 forks source link

詳細・編集機能のレビュー #3

Open washogo opened 2 months ago

washogo commented 2 months ago

やりたいこと

  1. 一覧画面のtodoをクリックする
  2. 詳細画面に遷移する
  3. 編集ボタンをクリックする
  4. 編集画面に遷移する
  5. 編集して更新ボタンをクリックする

レビュー

1. 一覧画面のtodoをクリックする

src/app/todos/page.tsxについて、以下のようにparamsidを受け取るようにしていますが、一覧画面でパスは/todosとなり、idは含まれないので取得できないですね。それにより、URLのid部分がundefinedとなっていたのだと思います。

import TodoList from "@/components/TodoList";

export default async function Home({ params }: { params: { id: number } }) {
  return (
    <>
      <TodoList id={params.id} />
    </>
  );
}

各todoの詳細画面のURLについて、idは各todoが持っているので、それをURLに含める必要があります。 そのためには、src/components/TodoList.tsxの以下の箇所でdata.idをLinkコンポーネントのhrefに含めると良さそうですね。

      <Link href={`/todos/${id}`}>
        {data.map((data) => (
          <Card key={data.id} w={700} mx={370} mt={4} mb={4} shadow="lg">
            <CardBody>
              <Box>
                <HStack>
                  <Text>Todo番号:{data.id}</Text>
                </HStack>
                <br />
                <HStack>
                  <Text>Todoタイトル:{data.title}</Text>
                </HStack>
                <br />
                <HStack>
                  <Text>Todoステータス:{data.status}</Text>
                </HStack>
              </Box>
            </CardBody>
          </Card>
        ))}
      </Link>

具体的な実装イメージは以下のような感じです!

{data.map((data) => (
    <Link key={data.id} href={`/todos/${data.id}`}>
        <Text>{data.title}</Text>
        <Text>{data.status}</Text>
    </Link>
)}

2. 詳細画面に遷移する

1の修正により詳細画面に遷移することができるようになると思います。

3. 編集ボタンをクリックする

src/app/todos/[id]/page.tsxでTodoArticleコンポーネントにidを渡す必要がありますが、現実装では渡されていないので、編集ボタンにあるLinkコンポーネントのhrefに使うidの取得ができずにudefinedとなっていますね。 そのため、src/app/todos/[id]/page.tsxについて、propsでidを受け取るようにしてください!

import TodoArticle from "@/components/TodoArticle";

const pageId = () => {
  return (
    <>
      <TodoArticle />
    </>
  );
};

export default pageId;

また、TodoArticleコンポーネントは以下のようにTodoData型のpropsを受け取るようになっていますが、idだけで良いかと思います!

const TodoArticle = ({ id }: TodoData) => {
  // const data: paramsProps = await getTodos(id);

  return (

4. 編集画面に遷移する

3の修正により編集画面に遷移することができるようになると思います。

5. 編集して更新ボタンをクリックする

1~4までの対応により編集画面で想定通りに編集することができるようになるかと思います。

編集のリクエストについて

【編集のリクエストのパスについて】 ①編集のリクエストのパスですが、TodoEditコンポーネントにfetchで指定しているURLでは2枚目の画像のエラーが表示されていました。Linkとは関係なさそうです。 ※URLについては前回質問した際にご指摘いただいたhttp://localhost:3000/api/todos/${id}に修正済みです。 ②APIの/api/todos/[id]のfindUniqueやupdateにてidが見つからないというエラーも表示されているのですが、どこを修正していけばいいか分かりませんでした。やはりidはuuidなどを使って指定した方がいいのでしょうか?

これはidは数値出ることが期待されますが、現実相ではundefinedとなってしまっているために発生しているエラーだと思いますね。 そのため、1~4までの対応により解消されるかと思います。

編集画面の表示について

③現在、TodoEditコンポーネントにfetchを使って編集ページに一覧や詳細に表示されているタイトルなどの値を同じように表示させているつもりですが、fetchを使ったコードをこのコンポーネントに記述するということでいいのでしょうか?

これは編集画面の各種入力欄を現在の値が入力された状態にしたいということですかね? 認識相違なければ、この場合はtodoをグローバルな状態として管理すると良さそうです! 具体的にはLocal StorageやRecoilやReactのContext APIを使って、編集画面に遷移する前に対象のtodoの情報を保存して、それを編集画面で利用するという実装となります。

y-u27 commented 2 months ago

【実装できた項目】

  1. 一覧画面のtodoをクリックする
  2. 詳細画面に遷移する

【実装できなかった項目】

  1. 編集ボタンをクリックする
  2. 編集画面に遷移する   └親コンポーネントにpropsとしてidを設定し、TodoArticleにそのidを渡したつもりだが、画面遷移後のURLにはundefinedが含まれてしまった。

【未実装】

  1. 編集して更新ボタンをクリックする

※【編集画面の表示について】 相違ありませんので、後ほど実装していきます。

washogo commented 2 months ago

@y-u27

3・4は親コンポーネントにidをpropsとして設定後、子コンポーネントであるTodoArticleの引数にidを渡したのですが、編集画面遷移後のURLにはundefinedが含まれていました。TodoArticleのコードにはエラーは出ていなかったです

こちらについて、page.tsxでは以下2つのpropsを受け取ることができる仕様です。それ以外は受け取ることができないと考えていただいて大丈夫です。

  1. params
  2. searchParams

そのため、src/app/todos/[id]/page.tsxについて、以下のようにpropsを設定していますが、

import { Article } from "@/app/types/types";
import TodoArticle from "@/components/TodoArticle";

const pageId = ({ id }: Article) => {

  return (
    <>
      <TodoArticle id={id} />
    </>
  );
};

export default pageId;

idではなく、以下src/app/todos/[id]/edit/page.tsxのようにparamsを使うようにしてください!

import TodoEdit from "@/components/TodoEdit";

const editPage = ({ params }: { params: { id: number } }) => {
  return (
    <TodoEdit id={params.id} />
  )
};

export default editPage;

参考:https://nextjs.org/docs/app/api-reference/file-conventions/page