useFormContext example in Typescript with nested #2853
-
Hi, |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 7 replies
-
you mean with |
Beta Was this translation helpful? Give feedback.
-
All you have to do is pass the type of the form data you're expecting to import React from "react";
import { Controller, useForm, FormProvider, useFormContext } from "react-hook-form";
type FormData = {
name: string;
age: number;
}
export default function App() {
const methods = useForm<FormData>();
const onSubmit = (data: FormData) => console.log(data);
return (
<FormProvider {...methods}>
// pass all methods into the context
<form onSubmit={methods.handleSubmit(onSubmit)}>
<NestedInput />
<input type="submit" />
</form>
</FormProvider>
)
}
function NestedInput() {
const { control } = useFormContext<FormData>(); // retrieve all hook methods
return (
<Controller
control={control}
name="age" // This will be typed correctly
render={({ field }) => {
return <input {...field} />
}}
/>
);
} |
Beta Was this translation helpful? Give feedback.
-
My use case which led me to seeking out this discussion is creating reusable components that call Here's an example where the reusable component accepts a import React from "react";
import {
FormProvider,
useForm,
useFormContext,
type FieldValues,
type Path,
} from "react-hook-form";
type FormData = {
name: string;
age: number;
}
export default function App() {
const methods = useForm<FormData>();
const onSubmit = (data: FormData) => console.log(data);
return (
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit(onSubmit)}>
<NestedInput<FormData> name="name" /> // note that we call NestedInput with the FormData type
<input type="submit" />
</form>
</FormProvider>
)
}
function NestedInput<TFieldValues extends FieldValues>({ name }: { name: Path<TFieldValues> }) {
const { register } = useFormContext<TFieldValues>();
return <input {...register(name)} />;
} In the above example, Alternatively, you may want to define your component with a set import React from "react";
import {
FormProvider,
useForm,
useFormContext,
type FieldValues,
type Path,
} from "react-hook-form";
type FormData = {
name: string;
age: number;
}
export default function App() {
const methods = useForm<FormData>();
const onSubmit = (data: FormData) => console.log(data);
return (
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit(onSubmit)}>
<NestedInput<FormData> /> // note that we call NestedInput with the FormData type
<input type="submit" />
</form>
</FormProvider>
)
}
interface NestedInputValues extends FieldValues {
age: string;
}
function NestedInput<TFieldValues extends NestedInputValues>() {
const { register } = useFormContext<TFieldValues>();
const name = 'age' as Path<TFieldValues>;
return <input {...register(name)} />;
} In this example, by passing the The main downside is if your components are deeply nested then you'll need to prop drill the type all the way down from the form level. |
Beta Was this translation helpful? Give feedback.
All you have to do is pass the type of the form data you're expecting to
useFormContext
as in the following example: