Ein tiefgehender Blick auf Next.js 14 – Teil 4

Create, Read, Update und Delete – CRUD-Funktionen in Next

Create, Read, Update und Delete – CRUD-Funktionen in Next

Ein tiefgehender Blick auf Next.js 14 – Teil 4

Create, Read, Update und Delete – CRUD-Funktionen in Next


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.

React Server Components: Read

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;
guenther_wieruch_next_1

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.

guenther_wieruch_next_2

Abb. 2: Ansicht der PostPage

guenther_wieruch_next_3

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.

Server Actions: Create...