Skip to content

Add client side validation #1

Description

@kirill-konshin

I was writing an article on React 19 forms and Zod, and before submission I decided to do one more round of googling, if something similar already exists... and found your wonderful article.

Fun thing is that I ended up with almost exactly the same implementation as you, almost line by line the same where it matters.

So I'd like to share how I implemented client side validation, it's just a few more lines of code to what you already have.

If you extract validation from server action into a validation function, you can call it on client side as well, before calling server action ;)

function validate(formData) {
  const formDataObj = Object.fromEntries(formData);
  const { data, error } = addItemSchema.safeParse(formDataObj);
  if (error) {
    return { formData, errors: error.flatten().fieldErrors };
  }
  return { formData, data };
}

Just make sure it's not in actions file, as it's marked as "use server";, probably types.ts is the right place for it.

So your action becomes:

export async function addItemAction(
  _: AddItemState,
  formData: FormData,
): Promise<AddItemState> {
  const res = validate(formData);
  if (res.error) return res;
  addItem(res.data);
  revalidatePath("/");
  return {};
}

and on client side:

const [state, formAction] = useActionState<AddItemState, FormData>(
    async (prev, formData) => {
       const res = validate(formData);
       if (res.error) return res;
       return addItemAction(prev, formData);
    },
    {},
  );

This way you save a roundtrip to server and apply exactly the same validation in both realms.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions