Skip to content

Instantly share code, notes, and snippets.

@vunguyentuan
Created June 5, 2023 01:35
Show Gist options
  • Save vunguyentuan/3218b756ee97e7e143d08621ad10e52d to your computer and use it in GitHub Desktop.
Save vunguyentuan/3218b756ee97e7e143d08621ad10e52d to your computer and use it in GitHub Desktop.
custom hook
import { Button } from "components/ui/button";
import { useState } from "react";
import { z } from "zod";
const FormSchema = z.object({
name: z.string().min(1, "Name is required"),
email: z.string().email().min(1, "Email is required"),
});
type FormState = {
errors: any;
};
const useForm = ({
resolver,
defaultValues,
}: {
resolver: typeof FormSchema;
defaultValues: any;
}) => {
const [data, setData] = useState<any>({});
const [errors, setErrors] = useState<any>({});
// {
// email:
// {
// message: "Inalid email"
// }
// }
const handleSubmit =
(onSubmit: (data: any) => void) =>
(event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const data = new FormData(event.currentTarget);
const entries = Object.fromEntries(data.entries());
try {
resolver.parse(entries);
onSubmit(entries);
setErrors({});
} catch (parseErrors) {
if (parseErrors instanceof z.ZodError) {
console.log(parseErrors.issues);
console.log(parseErrors.formErrors);
const errorMessage = Object.keys(
parseErrors.formErrors.fieldErrors
).reduce((result, key) => {
//@ts-ignore
const errorMessages = parseErrors.formErrors.fieldErrors[key];
if (errorMessages?.length === 0) {
return result;
}
return {
...result,
[key]: {
message: errorMessages
? errorMessages[errorMessages.length - 1]
: undefined,
},
};
}, errors);
console.log(errorMessage);
setErrors(errorMessage);
}
}
};
const register = (name: string) => {
return {
name,
value: data[name] ?? defaultValues[name],
onChange: (event: React.ChangeEvent<HTMLInputElement>) => {
console.log(event.target.value);
setData({ [name]: event.target.value });
},
};
};
const formState: FormState = {
errors: errors,
};
return {
handleSubmit,
register,
formState,
};
};
export default function Home() {
const { register, handleSubmit, formState } = useForm({
resolver: FormSchema,
defaultValues: {
name: "Vu",
},
});
const onSubmit = (data: any) => {
console.log(data);
};
return (
<main>
<form className="mt-10" onSubmit={handleSubmit(onSubmit)}>
<div>
<label>
Name
<input {...register("name")} />
</label>
</div>
<div className="mt-5">
<label>
Email
<input name="email" type="text" />
{formState.errors?.email && (
<p className="text-red-600">{formState.errors?.email?.message}</p>
)}
</label>
</div>
<Button className="mt-10">Submit</Button>
</form>
</main>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment