#Multi-step form with `useFormstate`

3 messages · Page 1 of 1 (latest)

spare wasp
#

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 ?

distant swiftBOT
#

🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord

🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in id:customize

✅ You can mark a message as the answer for your post with Right click -> Apps -> Mark Solution
(if you don't see the option, try refreshing Discord with Ctrl + R)

dry kindle
#

formData.get("xxx") is null mean the formData object doesn't contain your input field data inside the Step component