Asynchrone Datenänderungen und -verarbeitung ist eine notwendige Aufgabe in modernen Webanwendungen. Manchmal möchte man eine eigenständige asynchrone Funktion auf dem Server ausführen, um Aufgaben wie das Speichern von Daten im Datenstore, das Senden von E-Mails, das Herunterladen von PDFs, die Verarbeitung von Bildern und so weiter durchzuführen.

Next.js stellt uns die Server Aktionen zur Verfügung, die asynchrone Funktionen auf dem Server sind. Wir können Server Aktionen für Datenmutationsvorgänge auf dem Server verwenden, aber Server Aktionen können sowohl von Server- als auch von Clientkomponenten aufgerufen werden.

Server Aktionen sind eine großartige Methode, um Formulardaten bei der Übergabe auszuführen. In diesem Artikel untersuchen wir eine praktische Anwendung der Verarbeitung zusätzlicher Argumente in Next.js-Serveraktionen.

Wenn Sie sich für das Erlernen von Next.js-Serveraktionen mit Designmustern und Projektbau interessieren, habe ich ein Crashkurs für Sie erstellt, den Sie hier finden können.

Außerdem ist dieser Artikel auch als Video-Tutorial verfügbar:

Inhaltsverzeichnis

  1. Warum müsste man zusätzliche Argumente übergeben?

  2. Ein Formular mit einer Serveraktion

  3. Wie man zusätzliche Argumente übergeben

  4. Was geschieht mit den Hidden Fields?

  5. Ressourcen

Warum müsste man zusätzliche Argumente übergeben?

Wenn wir eine Server-Aktion bei einer Formularübergabe ausführen, erhält die Server-Aktion die Formulardaten automatisch. Zum Beispiel sehen Sie das untenstehende Formular:

<form className="p-4 flex" action={updateUser}>
  <Input className="w-1/2 mx-2" type="text" name="name" />
  <Button type="submit">Update User Name</Button>
</form>

Hier führen wir eine Server-Aktion namens updateUser aus, wenn das Formular abgeschickt wird. Die updateUser Funktion erhält die übermittelten Formulardaten als Argument, das verwendet werden kann, um die Formularfelddaten zu extrahieren.

Wie Sie in dem Codebeispiel unten sehen können, erhält die updateUser Funktion ein formData als Argument und wir können den Wert des name Feldes daraus extrahieren.

"use server"

export async function updateUser(formData) {
  const name = formData.get('name');
  console.log(name);
}

Während dieses Muster die meisten grundlegenden Anwendungsfälle abdeckt, könnten Sie programmatisch zusätzliche Argumente an die Serveraktionen übergeben müssen. Diese Argumente gehören nicht zu dem Formular, den Formulardaten oder den Benutzereingaben. Es handelt sich um programmatisch übermittelte Werte an Ihre Serveraktion.

Um dies zu verstehen, schauen Sie sich den untenstehenden Codeausschnitt der Serveraktion an. Es handelt sich um dieselbe Serveraktion, die wir zuvor gesehen haben, aber wir haben ein zusätzliches userId-Argument neben dem regulären formData-Argument übergeben.

"use server"

export async function updateUser(userId, formData) {
  const name = formData.get('name');
  console.log(userId);
  console.log(name);
}

Der Wert von userId ist etwas interner zu Ihrer Anwendung – und Sie würden dem Benutzer nicht verlangen, diesen Wert als Teil der Formularübergabe einzugeben. Stattdessen müssen Sie ihn programmatisch an Ihre Serveraktion übergeben, um weitere Berechnungen durchzuführen.

Richtig, das ist der Anwendungsfall, den wir hier erörtern. Da wir verstehen, warum wir das tun müssen, lassen Sie uns erkennen, wie wir das erreichen können. Aber zuerst lassen Sie uns ein Formular und eine funktionierende Serveraktion dafür erstellen.

Ein Formular Mit Einer Serveraktion

Erstellen Sie ein Verzeichnis namens actions unter dem Verzeichnis app Ihrer Next.js-Anwendung. Jetzt erstellen Sie eine Datei namens user.js im Ordner actions mit dem folgenden Code:

"use server"

export async function updateUser(formData) {
  const name = formData.get('name');
  console.log(name);

  // Führen Sie mit dem Namen alles mögliche durch: in die DB speichern, Rechnung erzeugen, was auch immer!
}

Dadurch können Sie eine Serverfunktion in Next.js erstellen. Der Datei muss eine ”use server”-Direktive am Anfang der Datei stehen, um Next.js zu sagen, dass dies eine besondere Datei mit einer oder mehreren asynchronen Funktionen ist, die auf dem Server ausgeführt werden sollen.

Wir haben nun die Serveraktion (die asynchrone Funktion) `updateUser` mit `formData` als Argument. Innerhalb der Funktionsdefinition extrahieren wir den Wert von `name` und schreiben ihn in die Konsole.

Lassen Sie uns nun diese Serveraktion einem Formular hinzufügen. Um das zu tun, erstellen Sie einen Ordner namens `components` im Stammverzeichnis des Projekts. Erstellen Sie eine Datei namens `user-form.jsx` mit dem folgenden Code:

import { Input } from "./ui/input"
import { Button } from "./ui/button"

import { updateUser } from "@/app/actions/user"

const UserForm = () => {
  return(
    <form className="p-4 flex" action={updateUser}>
      <Input className="w-1/2 mx-2" type="text" name="name" />
      <Button type="submit">Update User Name</Button>
    </form>
  )
}

export default UserForm;

Dies ist ein einfaches React-Komponenten mit einem Formular. Das Formular hat einen Eingabefeld für Text namens `name` und ein Senden-Button, um das Formular abzusenden. Das Formular hat ein `action`-Attribut mit der Serveraktion `updateUser` als Wert. Jetzt, wenn das Formular mit einem `name`-Wert abgesendet wird, erhält die Serveraktion diesen als Teil der Formulardaten, wie wir oben diskutiert haben.

Lassen Sie uns es testen. Um das zu tun, erstellen wir eine Next.js-Route und Seite, in der wir die `UserForm`-Komponente verwenden können. Erstellen Sie einen Ordner namens `extra-args` im Verzeichnis `app`. Jetzt erstellen Sie eine Datei namens `page.js` im Verzeichnis `app/extra-args` mit dem folgenden Code:

import UserForm from "@/components/user-form";

const ExtraArgsDemo = () => {
  return (
    <UserForm />
  )
}

export default ExtraArgsDemo;

Dies ist ein einfaches React-Komponenten, in dem wir die `UserForm`-Komponente importiert und in der JSX verwendet haben. Jetzt starten Sie den lokalen Server und rufen diese Route `localhost:3000/extra-args` auf. Sie sollten das Formular mit einem Textfeld und einem Button sehen.

Geben Sie im Textfeld etwas Text ein und klicken Sie auf den Button.

Nun kannst du sehen, dass der eingegebene Text auf der Serverkonsole gedruckt wurde. Warum auf der Serverkonsole und nicht im Browser-Konsole? Das liegt daran, dass Serveraktionen auf dem Server und nicht auf der Clientseite des Browsers ausgeführt werden.

Also haben wir nun eine Datenfluss-Struktur wie folgt etabliert:

Seite => Form => Serveraktion

Die Seite hat ein Formular. Beim Absenden des Formulars führt die Serveraktion einen Serverprozess durch. Die Serveraktion gibt die Formulardaten auf der Serverkonsole aus.

Lassen Sie uns nun diese Teile verbessern, um zusätzliche Argumente an die Serveraktion weiterzugeben.

Wie man zusätzliche Argumente weitergibt

Legen wir nun einen Propzen namens userId auf die UserForm-Komponente auf der Seite fest. Wir geben einen Wert für userId an, um zu vorgeben, dass wir dieses userId programmatisch an unser Formular und anschließend an die Serveraktion weitergeben.

import UserForm from "@/components/user-form";

const ExtraArgsDemo = () => {
  return (
    <UserForm userId={"1234"} />
  )
}

export default ExtraArgsDemo;

In der UserForm-Komponente nehmen wir den userId-Propzen an. Jetzt müssen wir etwas besonderes tun, um diesen userId an die updateUser-Serveraktion weiterzugeben.

JavaScript verfügt über eine magische Methode namens bind(), die uns dabei hilft, eine partielle Anwendungsfunktion zu erstellen. Mit dieser partialisierten Anwendungsfunktion kannst du eine Funktion aus einer anderen Funktion mit vorgefertigten Argumenten erstellen.

In unserem Fall besitzt die Funktion updateUser bereits ein Argument namens formData. Jetzt können wir das userId als zusätzliches Argument übergeben, indem wir die Methode bind() verwenden, um eine neue Funktion zu erzeugen.

const updatedUserWithId = updateUser.bind(null, userId);

Der erste Argument des bind()-Verfahrens ist die Kontext, dem Sie die Funktion zuordnen. Der Kontext handhabt die Assoziation der Funktion mit dem Wert des Schlüsselworts this. In unserem Fall können wir es als null behalten, da wir es nicht ändern. Anschließend haben wir das neue Argument userId übergeben. Es ist interessant zu wissen, dass die Methode bind() sowohl für Server- als auch für Clientkomponenten funktioniert.

Hier ist der geänderte Komponentenabschnitt UserForm (Datei user-form.jsx). Beachten Sie, dass der Wert der Formularaktion nun auf die neue Funktion updatedUserWithId geändert wurde.

import { Input } from "./ui/input"
import { Button } from "./ui/button"

import { updateUser } from "@/app/actions/user"

const UserForm = ({userId}) => {
  const updatedUserWithId = updateUser.bind(null, userId);

  return(
    <form className="p-4 flex" action={updatedUserWithId}>
      <Input className="w-1/2 mx-2" type="text" name="name" />
      <Button type="submit">Update User Name</Button>
    </form>
  )
}

export default UserForm;

Nun erhält die Serveraktion das userId-Argument als Argument. Lasst uns das auch in die Konsole schreiben.

"use server"

export async function updateUser(userId, formData) {
  const name = formData.get('name');
  console.log(userId);
  console.log(name);

  // tun mit dem user id und dem name was du willst, speichern Sie es in der Datenbank,
  // erstellen Sie eine Rechnung oder was auch immer!
}

Wenn Sie das Formular mit einem Namenwert abschicken:

Sie sehen, dass sowohl das userId als auch der Name-Wert in die Serverkonsole geschrieben werden. Großartig! Wir haben einen Wert aus dem Formulardatenlog gegeben und der andere wurde intern an die Serveraktion weitergegeben.

Also haben wir gelernt, wie man zusätzliche Argumente an die Serveraktion mit dem Formulardaten übergeben kann.

Wie geht es mit den versteckten Feldern?

HTML unterstützt ein verstecktes Formularfeld, um Daten vom Client an den Server zu übertragen, ohne die Eingabe der Benutzer zu akzeptieren. Das bedeutet, dass wir das versteckte Feld verwendet hätten, um den Wert von userId wie folgt zu übergeben:

Warum haben wir dann all das mit der Methode bind() gemacht? Nun, wegen Sicherheitsbedenken. Wenn Sie Daten mit versteckten Feldern übergeben, wird der Wert Teil des gerenderten HTML sein und nicht codiert werden. Daher ist es besser, es programmgesteuert zu handhaben.

Ressourcen

Das war’s vorerst. Hat Ihnen dieser Artikel gefallen und haben Sie etwas Neues gelernt? Wenn ja, würde ich gerne wissen, ob der Inhalt hilfreich war. Lassen Sie mich ein paar zusätzliche Ressourcen teilen, die Sie benötigen könnten:

Darüber hinaus können Sie sich mit mir verbinden, indem Sie:

  • Meinen YouTube-Kanal abonnieren. Wenn Sie lernen möchten, React und sein Ecosystem, wie Next.js, mit sowohl grundlegenden Konzepten als auch Projekten, habe ich eine großartige Nachricht für Sie: Sie können diese Playlist auf meinem YouTube-Kanal mit 25+ Video-Tutorials und über 15 Stunden anspruchsvollen Inhalten bis jetzt kostenlos anschauen. Ich hoffe, Sie mögen sie auch.

  • Folgen Sie mir auf X (Twitter) oder LinkedIn, wenn Sie die tägliche Dosis an Up-Skill-Tips nicht verpassen wollen.

  • Überprüfen und folgen Sie meinem Open-Source-Arbeiten auf GitHub.

  • Ich veröffentliche regelmäßig bedeutsame Beiträge auf meinem GreenRoots Blog, die Ihnen vielleicht auch hilfreich sein können.

Bis zum nächsten Artikel morgen. Bis dahin, verwahre dich selbst gut auf und lerne weiter.