0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

B2BエンジニアがT3 Stackに入門してみたAdvent Calendar 2022

Day 11

t3-stack入門 (9) Todoフォームのリファクタリング

Posted at

TodoEditコンポーネントがちょっとゴチャゴチャしてきたので整理します。

カスタムフックの作成

TodoEditで利用しているHookをカスタムフックにして、src/hooks/todo.tsに追い出します。

import { createTodoSchema } from "../schema/todo";
import { trpc } from "../utils/trpc";
import { useForm, zodResolver } from "@mantine/form";
import { useEffect } from "react";
import { type EditingTodo } from "../types/todo";

const useTodoEdit = (editingTodo: EditingTodo) => {
  const utils = trpc.useContext();
  const form = useForm({
    initialValues: {
      id: null as number | null,
      title: "",
      description: "",
    },
    validate: zodResolver(createTodoSchema),
  });
  useEffect(() => {
    form.setValues(editingTodo);
  }, [editingTodo]);

  const createTodo = trpc.todo.create.useMutation({
    onSettled: () => {
      utils.todo.getAll.invalidate();
    },
  });
  const updateTodo = trpc.todo.update.useMutation({
    onSettled: () => {
      utils.todo.getAll.invalidate();
    },
  });
  return { form, createTodo, updateTodo };
};

export default useTodoEdit;

Updateに必要なTodoの情報をTodoEdit内部で取得する

Updateに必要なTodoの情報を、TodoEditにprops経由で伝えていますがちょっと微妙な気がします。
たまたま今回はTodo一覧にUpdateに必要なTodoの情報がすべてそろっていましたが、いつもそうとは限りません。
また、Updateに必要なTodoの情報が変化したとき、TodoEdit内部だけでなく、利用側も変更が必要です。
TodoEditに渡す情報は必要最低限(Todoのid)で、必要な情報はTodoEdit内部で取得したほうがよいでしょう。

というわけで、propsで渡されたidからTodoデータをtrpcでとってきて、そのデータが更新されたらsetValuesを呼び出すことにします。

@@ -14,9 +14,15 @@ const useTodoEdit = (editingTodo: EditingTodo) => {
     },
     validate: zodResolver(createTodoSchema),
   });
+  const { data } = trpc.todo.get.useQuery(
+    { id: editingTodoId as number },
+    { enabled: editingTodoId != null }
+  );
   useEffect(() => {
-    form.setValues(editingTodo);
-  }, [editingTodo]);
+    if (data) {
+      form.setValues(data);
+    }
+  }, [data?.id]);

最初、editingTodoIdがnullだったらuseQueryを実行してsetValueを実行しようとしていたのですが、hooksをif分内で使用してはいけないという制約があるので、うまくいきませんでした。最終的にTanstack queryにenableオプションというのが用意されていたので、editingTodoIdがnullでない時だけQueryを実行するように変更しました。

ここまでの変更は以下の通りです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?