Replies: 5 comments 7 replies
-
Could you please describe more details what you want achieve with react router v6 and react-hook-form ? A codesandbox to show the problem will be helpful. Since routing library and form library are solving different use case, it always depends on developer logic implementation, not the libraries itself. |
Beta Was this translation helpful? Give feedback.
-
Any updates
|
Beta Was this translation helpful? Give feedback.
-
I have solved the issue by using a custom import { zodResolver } from "@hookform/resolvers/zod"
import { ReactNode } from "react"
import { FieldErrors, UseFormRegister, useForm } from "react-hook-form"
import { useSubmit } from "react-router-dom"
import { ZodType, z } from "zod"
interface Props<Validator extends ZodType<any, any, any>> {
validator: Validator
children: (register: UseFormRegister<z.infer<Validator>>, errors: FieldErrors<z.infer<Validator>>) => ReactNode
}
export default function Form<Validator extends ZodType<any, any, any>>(props: Props<Validator>) {
const submit = useSubmit()
const {
register,
handleSubmit,
formState: { errors },
} = useForm<z.infer<Validator>>({ resolver: zodResolver(props.validator) })
return (
<form
method="post"
onSubmit={(event) => {
const target = event.currentTarget
handleSubmit(() => {
submit(target, { method: "post" })
})(event)
}}
>
{props.children(register, errors)}
</form>
)
} This component can be used like this: import clsx from "clsx"
import { redirect, ActionFunctionArgs, useNavigation } from "react-router"
import { ulid } from "ulid"
import { z } from "zod"
import Form from "./Form"
const validation = z.object({
firstName: z.string().trim().nonempty(),
lastName: z.string().trim().nonempty(),
})
type FormData = z.infer<typeof validation>
export async function action({ request }: ActionFunctionArgs) {
const formData = Object.fromEntries(await request.formData()) as FormData
const id = ulid()
// Register logic here
return redirect(`../${id}`)
}
export default function Add() {
const { state } = useNavigation()
return (
<Form validator={validation}>
{(register, errors) => (
<>
<label className="label" htmlFor="firstName">
<span className="label-text">First name</span>
</label>
{errors.firstName && <p className="text-sm italic text-error">{errors.firstName.message}</p>}
<input
id="firstName"
{...register("firstName")}
type="text"
className={clsx("input input-bordered", {
"input-error": !!errors.firstName,
})}
/>
<label className="label" htmlFor="lastName">
<span className="label-text">Last name</span>
</label>
{errors.lastName && <p className="text-sm italic text-error">{errors.lastName.message}</p>}
<input
id="lastName"
{...register("lastName")}
type="text"
className={clsx("input input-bordered", {
"input-error": !!errors.lastName,
})}
/>
<button type="submit" className="btn btn-primary" disabled={state === "submitting"}>
{state === "submitting" && <span className="loading loading-spinner loading-sm" />}
Save
</button>
</>
)}
</Form>
)
} |
Beta Was this translation helpful? Give feedback.
-
It's definitely terrible in v6. Why react router want to become a form library? |
Beta Was this translation helpful? Give feedback.
-
import { useForm } from "react-hook-form";
import { useSubmit } from "react-router-dom";
export async function action({ request }) {
const data = await request.json();
}
export default function App() {
const { register, handleSubmit } = useForm();
const submit = useSubmit();
const onSubmit = (data) => {
submit(data, {
method: "post",
action: "/",
encType: "application/json",
});
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("example")} />
<input type="submit" />
</form>
);
} |
Beta Was this translation helpful? Give feedback.
-
If you want to use the full power of react router dom, react router dom will control the form and submit, so it will share responsibility with react form hook and this leads to inefficiencies and problems. It cannot be that the most powerful routing library and the most powerful form control and validation library do not have any type of integration for v6 of react router and thus the two libraries can work together in optimal conditions. The two development teams behind these marvelous libraries should be talked about and that react router dom encourages integration with third parties so that their system works well.
remix-run/react-router#10080
remix-run/react-router#10079
Beta Was this translation helpful? Give feedback.
All reactions