Ein tiefgehender Blick auf Next.js 14 – Teil 4
Ein tiefgehender Blick auf Next.js 14 – Teil 4
Nachdem wir uns in den vorhergehenden Ausgaben intensiv mit Formularen und der Authentifizierung in einer Next.js-App beschäftigt haben, widmet sich dieser Teil dem Thema CRUD. Dabei tauchen wir weiter in das Thema Server Actions in Next.js 14 mit App Router und React Server Components (RSC) ein.
Das Tutorial zeigt, wie Server Actions verwendet werden, um Create, Read, Update und Delete (CRUD) zu implementieren.
Nach Abschluss des Workshops zur Authentifizierung [1] haben Sie bereits erste Daten aus einer Prisma-Abfrage in einer Server Component gerendert (Abb. 1). Listing 1 zeigt den Ausgangspunkt für dieses Tutorial. Wir knüpfen genau dort an, wo wir die Erkundung der Authentifizierung im Entwickler Magazin 6.2024 beendet haben.
Listing 1
// src/app/page.tsx
import { prisma } from '@/lib/prisma';
const PublicHomePage = async () => {
const posts = await prisma.post.findMany();
return (
<div className="p-4 flex flex-col gap-y-4">
<h2>Home</h2>
<ul className="flex flex-col gap-y-2">
{posts.map((post) => (
<li key={post.id}>{post.name}</li>
))}
</ul>
</div>
);
};
export default PublicHomePage;
Abb. 1: Daten aus einer Prisma-Abfrage in einer Server Component gerendert
Zu Beginn implementieren wir eine Funktion zum Abrufen eines einzelnen Posts (Abb. 2). Dazu verwenden wir die in Next.js integrierte Link Component (Listing 2). Mit dieser erstellen wir den Link Go To (Abb. 3), der zu einer neuen Page (Listing 3) führt. Letztere zeigt den Inhalt des jeweiligen Posts an.
Abb. 2: Ansicht der PostPage
Abb. 3: Der Link Go To führt zur PostPage
Listing 2
import { prisma } from '@/lib/prisma';
import Link from 'next/link';
const PublicHomePage = async () => {
const posts = await prisma.post.findMany();
return (
<div className="p-4 flex flex-col gap-y-4">
<h2>Home</h2>
<ul className="flex flex-col gap-y-2">
{posts.map((post) => (
<li key={post.id} className="flex items-center gap-x-4">
<div>{post.name}</div>
<div>
<Link className="text-blue-600 hover:underline" href={`/posts/${post.id}`}>Go To</Link>
</div>
</li>
))}
</ul>
</div>
);
};
export default PublicHomePage;
Wir nutzen die postId aus dem URL, um die Daten des Posts aus der Datenbank abzurufen. Damit die Komponente PostPage gerendert werden kann, muss das Ergebnis der Datenabfrage vorliegen. Daher verwenden wir das Schlüsselwort await via Server Component (Listing 3).
Listing 3
// src/app/posts/[postId]/page.tsx
import { notFound } from 'next/navigation';
import { prisma } from '@/lib/prisma';
type PostPageProps = {
params: {
postId: string;
};
};
const PostPage = async ({ params }: PostPageProps) => {
const post = await prisma.post.findUnique({
where: {
id: params.postId,
},
});
if (!post) {
return notFound();
}
return <h2>{post.name}</h2>;
};
export default PostPage;
Jetzt möchten wir die Möglichkeit hinzufügen, einen Post zu erstellen, zu bearbeiten und zu löschen. Dazu nutzen wir Server Actions, sodass es nicht notwendig ist, eine Server Component in eine Client Component umzuwandeln.