RHFController
Core wrapper component for React Hook Form integration
You are reading the v1 docs. v2 renamed several props and replaced GeckoUIPortal with GeckoUIProvider. Read this page in v2.
Live examples are only rendered in the v2 docs.
RHFController
RHFController is a wrapper around React Hook Form's Controller component that automatically injects the control prop from FormProvider. This is the foundation for all RHF* components in Gecko UI.
Installation
import { RHFController } from '@geckoui/geckoui';Basic Usage
import { useForm, FormProvider } from 'react-hook-form';
import { RHFController } from '@geckoui/geckoui';
function Example() {
const methods = useForm({
defaultValues: {
email: ''
}
});
return (
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit(console.log)}>
<RHFController
name="email"
render={({ field }) => (
<input
{...field}
type="email"
placeholder="Enter email"
/>
)}
/>
</form>
</FormProvider>
);
}Props API
Accepts all props from React Hook Form's Controller:
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | - | Field name (required) |
control | Control | Auto-injected | Optional: Pass explicitly for nested forms or custom form context |
render | function | - | Render prop function (required) |
defaultValue | any | - | Default field value |
shouldUnregister | boolean | false | Unregister field on unmount |
About control prop: By default, RHFController uses useFormContext() to get the control object automatically. Pass it explicitly when you have nested FormProviders and want to connect to a specific form instance.
Why Use RHFController?
Without RHFController (Standard RHF)
import { Controller, useFormContext } from 'react-hook-form';
function CustomInput() {
const { control } = useFormContext();
return (
<Controller
control={control} // Must manually get and pass control
name="email"
render={({ field }) => <input {...field} />}
/>
);
}With RHFController (Gecko UI)
import { RHFController } from '@geckoui/geckoui';
function CustomInput() {
return (
<RHFController
name="email" // control is auto-injected!
render={({ field }) => <input {...field} />}
/>
);
}Examples
Access Form State
<RHFController
name="password"
render={({ field, fieldState, formState }) => (
<div>
<input {...field} type="password" />
{fieldState.error && (
<span>{fieldState.error.message}</span>
)}
{formState.isDirty && <span>Unsaved changes</span>}
</div>
)}
/>Custom Component Integration
<RHFController
name="birthDate"
render={({ field }) => (
<CustomDatePicker
value={field.value}
onChange={field.onChange}
onBlur={field.onBlur}
/>
)}
/>Nested FormProviders
When you have nested forms, pass control explicitly to specify which form:
function NestedFormsExample() {
const outerForm = useForm({ defaultValues: { outerField: '' } });
const innerForm = useForm({ defaultValues: { innerField: '' } });
return (
<FormProvider {...outerForm}>
<FormProvider {...innerForm}>
{/* Uses innerForm's control automatically */}
<RHFController
name="innerField"
render={({ field }) => <input {...field} />}
/>
{/* Explicitly use outerForm's control */}
<RHFController
name="outerField"
control={outerForm.control}
render={({ field }) => <input {...field} />}
/>
</FormProvider>
</FormProvider>
);
}When to Use
Use RHFController When:
- Building custom form components
- Integrating third-party libraries
- Need fine-grained control over field behavior
Use Pre-built RHF Components When:
- Working with Gecko UI components
- Want automatic error styling
- Need less boilerplate
Related Components
- RHFInput - Text input wrapper
- React Hook Form Controller - Official docs