Asynchrone gegevensverandering en -behandeling is een noodzakelijke taak in moderne webapplicaties. U zou misschien een losstaande asynchrone functie op de server willen uitvoeren om taken uit te voeren zoals gegevens opslaan in de gegevensopslag, e-mails versturen, PDF’s downloaden, afbeeldingen verwerken, enzovoort.

Next.js biedt ons aan Serveracties die asynchrone functies zijn die op de server worden uitgevoerd. We kunnen serveracties gebruiken voor gegevensmutaties op de server, maar serveracties kunnen worden aangeroepen vanuit zowel server- als clientcomponenten.

Serveracties zijn een geweldige manier om formulierondersteuning af te handelen door de actie uit te voeren wanneer formuliergegevens worden ingediend. In dit artikel zullen we een praktische toepassing bekijken van het behandelen van aanvullende argumenten in Next.js-serveracties.

Als u geïnteresseerd bent in het leren van Next.js-serveracties met ontwerpp patronen en het bouwen van projecten, heb ik een crashcursus voor u gemaakt die u hier kunt vinden.

Ook is dit artikel beschikbaar als video-tutorial:

Inhoudsopgave

  1. Waarom Zou U Extra Argumenten Moeten Overdragen?

  2. Een Formulier met een Serveractie

  3. Hoe toegang krijgen tot extra argumenten

  4. Wat betreft de verborgen velden?

  5. Bronnen

Waarom zou je extra argumenten moeten doorgeven?

Als we een serveractie uitvoeren bij het indienen van een formulier, krijgt de serveractie de formuliergegevens automatisch. Bijvoorbeeld, kijk bij het formulier hieronder:

<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 zijn we een serveractie genaamd updateUser aanroeppend als het formulier wordt ingediend. De updateUser functie zal de ingediende formuliergegevens als een argument ontvangen, die kan worden gebruikt om de waarden van de formuliervelden uit te trekken.

Zoals u kunt zien in het codefragment hieronder, krijgt de updateUser functie een formData als argument, en we kunnen de waarde van het veld name eruit halen.

"use server"

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

Hoewel dit patroon de meeste basisgebruiksgevallen Coveert, moet u misschien programmatisch aanvullende argumenten doorgeven aan de serveracties. Deze argumenten zijn geen deel van het formulier of de formulardata of de gebruikersinvoerdata. Het kunnen waardes zijn die programmatisch doorgegeven zijn aan uw serveractie.

Om dit te begrijpen, kijk u op de code fragment voor de serveractie hieronder. Het is dezelfde serveractie die we eerder hebben gezien, maar we hebben een extra userId-argument meegegeven naast het reguliere formData-argument.

"use server"

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

De waarde van userId is iets interns binnen de applicatie – en u zou de gebruiker niet vragen om de waarde als onderdeel van het formulier in te dienen. In plaats daarvan moet u het waarschijnlijk programmatisch doorgeven aan uw serveractie om verdere berekeningen uit te voeren.

correct, dat is het gebruiksgeval waarover we spreken. Nu we begrijpen waarom we dit nodig hebben, leert ons hoe we dit kunnen achieveren. Maar eerst, laten we een formulier en een werking serveractie ervoor creëren.

Een Formulier Met Een Serveractie

Maak een directory genaamd actions onder de app directory van uw Next.js applicatie. Maak nu een user.js bestand onder de actions map met het volgende code:

"use server"

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

  // Do anything with the name, save in DB, create invoice, whatever!
}

Dit is hoe u een serverfunctie in Next.js creëert. Het moet een ”use server”-directive aan de bovenkant van het bestand hebben om Next.js te laten weten dat dit een speciaal bestand is met een of meer asynchronous functies om op de server uit te voeren.

Dan hebben we de serveractie (de asynchroon functie) `updateUser` met `formData` als argument. Binnen de functieomschrijving halen we de `name` waarde uit en printen we deze op de console.

Laten we deze serveractie nu aan een formulier koppelen. Om dit te doen, maak een map genaamd `components` onder het hoofdmap van het project. Maak een bestand genaamd `user-form.jsx` met het volgende 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;

Dit is een eenvoudig React-component met een formulier. Het formulier heeft één invoerveld voor tekst genaamd `name` en een verzendknop om het formulier in te dienen. Het formulier heeft een `action` attribuut met de serveractie `updateUser` als waarde. Nu, als het formulier wordt ingediend met een `name` waarde, krijgt de serveractie deze als onderdeel van de formuliergegevens, zoals we bovenop besproken hebben.

Testen we het eens uit. Om dit te doen, zal ik een Next.js-route en pagina aanmaken waar we de `UserForm`-component kunnen gebruiken. Maak een map genaamd `extra-args` onder het `app`-directory. Maak nu een bestand genaamd `page.js` in het `app/extra-args`-directory met het volgende code:

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

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

export default ExtraArgsDemo;

Dit is een eenvoudig React-component waarin we de `UserForm`-component hebben geïmporteerd en ermee in de JSX hebben gebruikt. Nu de lokale server draaien en deze route `localhost:3000/extra-args` bereiken. U zou het formulier moeten zien met een tekstveld en een knop.

Tik wat tekst binnen in het tekstveld en klik op de knop.

Nu zie je dat de ingevoerde tekst is afgedrukt op de serverconsole. Waarom op de serverconsole en niet in de browserconsole? Dit omdat serveracties worden uitgevoerd op de server, niet op de clientzijde in de browser.

Dus, met dit hebben we nu een dataflow opgebouwd zoals dit:

Pagina => Formulier => Serveractie

De pagina heeft een formulier. Het formulier voert een serveractie uit bij het verzenden. De serveractie print de formulardata op de serverconsole.

Laten we nu deze stukjes verbeteren om extra argumenten door te geven aan de serveractie.

Hoe om Extra Argumenten door te geven

Laat ons een prop toewijzen aan het UserForm-component van de pagina. We zullen een userId meegeven met een waarde om alsof we deze userId programmatisch doorgeven aan ons formulier en daarnaast aan de serveractie.

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

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

export default ExtraArgsDemo;

In het UserForm-component accepteren we de userId-prop. Nu moeten we iets speciaals doen om deze userId door te geven aan de updateUser-serveractie.

JavaScript heeft een magische methode genaamd bind() die ons helpt om een Gedeeltelijk Toegepaste Functie te creëren. Met deze gedeeltelijk toegepaste functie kun je een functie aanmaken uit een andere functie met vooraf ingestelde argumenten.

In ons geval heeft de functie `updateUser` al een argument genaamd `formData`. Nu kunnen we `userId` doorgeven als een extra argument door middel van de `bind()` methode om een nieuwe functie te maken.

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

Het eerste argument van de `bind()` methode is de context waar je de functie aanbindt. De context behandelt de associatie van de functie met de waarde van het sleutelwoord `this`. In ons geval kunnen we het bij `null` houden omdat we hem niet wijzigen. Daarna hebben we het nieuwe argument `userId` doorgegeven. Het is goed te weten dat de `bind()` methode werkt op zowel server- als clientcomponenten.

Hier is de aangepaste `UserForm` component (bestand `user-form.jsx`). Noteer dat de waarde van de formulieractie nu is gewijzigd naar de nieuwe functie `updatedUserWithId`.

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;

Nu zal de serveractie het `userId`-argument ontvangen. Laten we dat ook naar de console printen.

"use server"

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

  // Do anything with the user id and name, save in DB,
  // create invoice, whatever!
}

Als je nu het formulier indient met een waarde voor de naam:

Zult u zien dat zowel `userId` als de naamwaarden in de serverconsole worden gelogd. Goed! We hebben een waarde uit het formulardata geregistreerd en de andere werd intern doorgegeven aan de serveractie.

Dus hebben we geleerd hoe je extra argumenten aan de serveractie kunt doorgeven samen met de formulardata.

Wat over de verborgen velden?

HTML ondersteunt een verborgen type formulierveld om gegevens van de cliënt naar de server door te geven zonder de invoer van de gebruikers te accepteren. Dus betekent dit dat we het verborgen veld konden gebruiken om de waarde van userId zoals dit te doorsturen:

Maar waarom hebben we allemaal dat gedaan met de bind() methode? Wel, vanwege beveiligingsredenen. Wanneer u gegevens op een verborgen manier doorstuurt, zal de waarde deel uitmaken van de gerenderde HTML, en zal ze niet gecodeerd zijn. Het is dus beter dit programmatisch af te handelen.

Resources

Dat is nu alles. Heb je het artikel genoten en heb je iets nieuws geleerd? Als ja, zou ik het erg waarderen als u me vertelt of de inhoud van nut was. Laat me een aantal aanvullende bronnen delen die u misschien nodig hebt:

Bijkomend, kunt u met mij verbinden door:

  • Abonneren op mijn YouTube Kanaal. Als u een voorkeur heeft om over React en zijn ecosysteem te leren, zoals Next.js, met zowel fundamentele concepten als projecten, heb ik goede nieuwtjes voor u: u kunt deze afspeellijst op mijn YouTube kanaal bekijken met meer dan 25 video-tutorials en 15+ uur Engelstalig attractief content tot nu toe gratis. Ik hoop dat u ze ook leuk vindt.

  • Volgen met mij op X (Twitter) of LinkedIn als je niet wilt missen van de dagelijkse dosis van upskilling tips.

  • Bekijk en volg mijn Open Source werk op GitHub.

  • Ik publiceer regelmatig postings met betekenis op mijn GreenRoots Blog, misschien vindt u ze ook nuttig.

Blijf bij ons terug met mijn volgende artikel. tot dan, houd u van uzelf en blijf leren.