What
シンプルなGET, POSTです。
重要なのはuseEffectで初回のみfetchを発火します。
useStateのみだとfetchが遅れるためです。
以下のコードで、投稿と同時に表示されます。
Code
prisma/schema.prisma
model Task {
id Int @id @default(autoincrement())
title String @db.VarChar(255)
createdAt DateTime @default(now()) @db.Timestamp(6)
}
ホットリロードでインスタンス大量生成されるのを防ぐコードです。👇️
lib/prisma.ts
import { PrismaClient } from "@prisma/client";
const globalForPrisma = global as unknown as {
prisma: PrismaClient | undefined;
};
if (!globalForPrisma.prisma) {
globalForPrisma.prisma = new PrismaClient();
}
const prisma: PrismaClient = globalForPrisma.prisma;
export default prisma;
api/task/route.ts
import { NextResponse } from "next/server";
import prisma from "@/app/lib/prisma";
export const POST = async (req: Request) => {
try {
const { title } = await req.json();
const task = await prisma.task.create({
data: {
title: title || "デフォルトタイトル",
},
});
return NextResponse.json({ message: "Task created successfully", task });
} catch (err) {
console.error("Error creating task:", err);
return NextResponse.json(
{ message: "Failed to create task" },
{ status: 500 }
);
}
};
export const GET = async () => {
try {
const tasks = await prisma.task.findMany();
return NextResponse.json({ message: "Success", tasks }, { status: 200 });
} catch (err) {
return NextResponse.json({ message: "Error", err }, { status: 500 });
} finally {
await prisma.$disconnect;
}
};
page.tsx
"use client";
import { useEffect, useRef, useState } from "react";
export default function Home() {
interface task {
id: number | null;
title: string;
createdAt: string | null;
}
const [tasks, setTasks] = useState<task[]>([]);
const fetchAllTasks = async () => {
const res = await fetch(`/api/task`, {
method: "GET",
});
const data = await res.json();
setTasks(data.tasks);
console.log(data.tasks);
};
const postTask = async (title: string) => {
const res = await fetch(`/api/task`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ title: title }),
});
fetchAllTasks();
return await res.json();
};
useEffect(() => {
fetchAllTasks();
}, []);
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (valueRef.current?.value) {
postTask(valueRef.current.value);
valueRef.current.value = "";
}
};
const valueRef = useRef<HTMLInputElement>(null);
return (
<div>
<form onSubmit={handleSubmit}>
<input type="text" ref={valueRef} />
<button type="submit">タスク作成</button>
</form>
<div>
{tasks.map((task) => (
<div key={task.id}>
{task.id}:{task.title}
</div>
))}
</div>
</div>
);
}
リロードしないで画面を更新するシンプルな方法です。
もっと良い方法があれば更新します。