-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuseFormServerAction.tsx
More file actions
58 lines (53 loc) · 1.88 KB
/
Copy pathuseFormServerAction.tsx
File metadata and controls
58 lines (53 loc) · 1.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import { useForm, UseFormProps } from "react-hook-form";
import { z, ZodSchema } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { FormEvent } from "react";
import { HookSafeActionFn, useAction } from "next-safe-action/hooks";
export type ServerActionContext = undefined;
type ServerActionError = string;
/**
* Built on top of {@link https://react-hook-form.com/docs/useform React Hook Form's `useForm`}
* and {@link https://next-safe-action.dev/docs/execute-actions/hooks/useaction next-safe-action's `useAction`},
* it provides both form state and action state.
*
* @param formSchema the Zod form schema.
* @param actionOnSubmit a server action that expects data of the same schema (created using `makeServerAction` from `@/lib/server/makeServerAction.ts`).
* @param options React Hook Form's `useForm` options.
*
* @returns an object with:
* - React Hook Form's `form` object
* - `formFieldErrors` that map each form field to a potential error
* - the `submit` function that you can pass to your form's `onSubmit`
* - the `action` object with its execution state (`isPending`, `data`, `error`, `isError`, `isSuccess`…).
*/
export function useFormServerAction<FormSchema extends z.ZodType, ReturnType>(
formSchema: FormSchema,
actionOnSubmit: HookSafeActionFn<
ServerActionError,
ZodSchema,
readonly [],
{
_errors?: string[] | undefined;
},
readonly [],
ReturnType
>,
options?: UseFormProps<FormSchema>
) {
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
mode: "onBlur",
...options,
});
const action = useAction(actionOnSubmit);
const submit = (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
void form.handleSubmit((input) => action.execute(input))(event);
};
return {
form,
fieldErrors: form.formState.errors,
submit,
action,
};
}