Next.js Discord

Discord Forum

Multi-step form with `useFormstate`

Unanswered
Barbary Lion posted this in #help-forum
Open in Discord
Barbary LionOP
Hello I'm trying to create a sign-up form in multiple steps using RSC. Here's what I've tried so far

// page.ts
"use client";

import { type ReactNode, useState } from "react";
import { useFormState } from "react-dom";

import { Step } from "./_components/Step";
import { Confirmation } from "./_components/Confirmation";
import { BasicInfo } from "./_components/BasicInfo";
import { Location } from "./_components/Location";

import { createUser } from "./actions";

export type CreateUserForm = {
  name: string;
  surname: string;
  location: string;
};

export default function Page() {
  const [state, formAction] = useFormState<CreateUserForm, FormData>(createUser, null);

  const [formIndex, setFormIndex] = useState(0);

  const forms: ReactNode[] = [
    <BasicInfo key="basic-info" />,
    <Location key="location" />,
    <Confirmation key="confirmation" />,
  ];

  const goBack = () => {
    if (formIndex > 0) {
      setFormIndex(formIndex - 1);
    }
  };

  const goNext = () => {
    if (formIndex < forms.length - 1) {
      setFormIndex(formIndex + 1);
    }
  };

  return (
    <form action={formAction}>
      <Step
        goBack={goBack}
        goNext={goNext}
        lastStep={formIndex === forms.length - 1}
      >
        {forms[formIndex]}
      </Step>
    </form>
  );
}


// actions.ts
"use server";

import { z } from "zod";
import { CreateUserForm } from "./page";

export const createUser = (prevState: CreateUserForm, formData: FormData) => {
  for (const data of formData.entries()) {
    console.log(data);
  }

  const schema = z.object({
    name: z.string(),
    surname: z.string(),
    location: z.string(),
  });

  const data = schema.parse({
    name: formData.get("name"),
    surname: formData.get("surname"),
    location: formData.get("location"),
  });

  // add the user in DB
  ...

  return data;
};


However zod always throws an error stating the formData.get("xxx") is null. Any idea what should I do ?

2 Replies

formData.get("xxx") is null mean the formData object doesn't contain your input field data inside the Step component
this is not gonna work, because when you change the state of formIndex, the page is gonna rerender and the formData will reset