react-hook-form-base
v1.0.4
Published
Reusable React Hook Form components
Maintainers
Readme
react-hook-form-base
A lightweight wrapper around React Hook Form that simplifies form creation while preserving the full power of React Hook Form.
It provides a reusable FormBase component and re-exports all React Hook Form APIs, making it easy to build scalable, reusable, and type-safe forms for both React and React Native.
Features
- 🚀 Minimal setup with
FormBase - 📦 Re-export all React Hook Form APIs
- 🎯 Fully typed with TypeScript
- ⚡ Lightweight and tree-shakable
- ♻️ Build reusable form components
- 🖥️ Supports React and React Native
- 🎨 Works with any UI library (Ant Design, Material UI, Chakra UI, NativeBase, etc.)
- ❤️ Powered by React Hook Form
Installation
Install the package:
yarn add react-hook-form-baseor
npm install react-hook-form-basePeer Dependencies
yarn add react react-dom react-hook-formFor React Native:
yarn add react react-native react-hook-formQuick Start
import { FormBase, Controller } from "react-hook-form-base";
interface LoginForm {
email: string;
password: string;
}
export default function LoginPage() {
return (
<FormBase
defaultValues={{
email: "",
password: "",
} as LoginForm}
onSubmit={(values) => {
console.log(values);
}}
>
{(form, submit) => (
<>
<Controller
control={form.control}
name="email"
render={({ field }) => (
<input
{...field}
placeholder="Email"
/>
)}
/>
<Controller
control={form.control}
name="password"
render={({ field }) => (
<input
{...field}
type="password"
placeholder="Password"
/>
)}
/>
<button onClick={submit}>
Login
</button>
</>
)}
</FormBase>
);
}API
FormBase
A wrapper around useForm that automatically provides FormProvider and a convenient submit function.
Props
| Prop | Type | Description |
|------|------|-------------|
| defaultValues | DefaultValues<T> | Initial form values |
| onSubmit | (values: T) => void | Called after successful validation |
| children | (form, submit) => ReactNode | Render function |
Re-exported APIs
All React Hook Form APIs are re-exported.
import {
Controller,
useForm,
useFormContext,
useController,
useWatch,
useFieldArray,
FormProvider,
} from "react-hook-form-base";No need to install or import directly from react-hook-form.
Using Custom Components
Controller makes integrating custom components straightforward.
<Controller
control={form.control}
name="username"
render={({ field, fieldState }) => (
<TextField
label="Username"
value={field.value}
onChange={field.onChange}
error={fieldState.error?.message}
/>
)}
/>This pattern allows you to build reusable components that work across your entire application.
UI Library Examples
Ant Design
import { Input } from "antd";
<Controller
control={form.control}
name="email"
render={({ field }) => (
<Input
{...field}
placeholder="Email"
/>
)}
/>Material UI
import TextField from "@mui/material/TextField";
<Controller
control={form.control}
name="firstName"
render={({ field, fieldState }) => (
<TextField
{...field}
label="First Name"
error={!!fieldState.error}
helperText={fieldState.error?.message}
/>
)}
/>Chakra UI
import { Input } from "@chakra-ui/react";
<Controller
control={form.control}
name="email"
render={({ field }) => (
<Input
{...field}
placeholder="Email"
/>
)}
/>TypeScript Support
react-hook-form-base fully preserves the generic typing provided by React Hook Form.
interface UserForm {
firstName: string;
lastName: string;
age: number;
}
<FormBase
defaultValues={{
firstName: "",
lastName: "",
age: 18,
} as UserForm}
onSubmit={(values) => {
console.log(values.age);
}}
>
{(form, submit) => (
...
)}
</FormBase>Type inference works automatically throughout the form.
React Native
The library works seamlessly with React Native.
The recommended approach is to create reusable input components using Controller together with useFormContext.
Reusable TextInputField
import React from "react";
import {
Text,
TextInput,
TextInputProps,
View,
StyleSheet,
} from "react-native";
import {
Controller,
FieldValues,
RegisterOptions,
useFormContext,
} from "react-hook-form-base";
interface TextInputFieldProps extends TextInputProps {
name: string;
label?: string;
rules?: Omit<
RegisterOptions<FieldValues, string>,
"disabled" | "valueAsNumber" | "valueAsDate" | "setValueAs"
>;
}
export function TextInputField({
name,
label,
rules,
...props
}: TextInputFieldProps) {
const { control } = useFormContext();
return (
<View style={styles.wrapper}>
{label && <Text style={styles.label}>{label}</Text>}
<Controller
control={control}
name={name}
rules={rules}
render={({ field, fieldState }) => (
<>
<TextInput
{...props}
value={field.value?.toString() ?? ""}
onChangeText={field.onChange}
onBlur={field.onBlur}
style={[
styles.input,
fieldState.error && styles.inputError,
]}
/>
{fieldState.error && (
<Text style={styles.error}>
{fieldState.error.message}
</Text>
)}
</>
)}
/>
</View>
);
}
const styles = StyleSheet.create({
wrapper: {
marginBottom: 16,
},
label: {
marginBottom: 6,
fontWeight: "600",
},
input: {
borderWidth: 1,
borderRadius: 8,
padding: 12,
borderColor: "#DDD",
},
inputError: {
borderColor: "#FF4D4F",
},
error: {
marginTop: 4,
color: "#FF4D4F",
fontSize: 12,
},
});React Native Form Example
import { Button } from "react-native";
import { FormBase } from "react-hook-form-base";
type LoginForm = {
email: string;
password: string;
};
export default function LoginScreen() {
return (
<FormBase
defaultValues={{
email: "",
password: "",
} as LoginForm}
onSubmit={(values) => {
console.log(values);
}}
>
{(form, submit) => (
<>
<TextInputField
name="email"
label="Email"
keyboardType="email-address"
rules={{
required: "Email is required",
}}
/>
<TextInputField
name="password"
label="Password"
secureTextEntry
rules={{
required: "Password is required",
}}
/>
<Button
title="Login"
onPress={submit}
/>
</>
)}
</FormBase>
);
}Why FormBase?
Without FormBase:
- Create
useForm - Wrap with
FormProvider - Call
handleSubmit - Pass methods manually
With FormBase:
- Configure once
- Receive form methods
- Call
submit() - Focus on building your UI
Less boilerplate. Same flexibility.
Roadmap
Current
- ✅ FormBase
- ✅ React Native support
- ✅ React Hook Form API re-export
Planned
- ⏳ InputField
- ⏳ TextAreaField
- ⏳ SelectField
- ⏳ CheckboxField
- ⏳ RadioField
- ⏳ SwitchField
- ⏳ DatePickerField
- ⏳ UploadField
- ⏳ ArrayField
- ⏳ Form validation helpers
Requirements
| Package | Version | |----------|---------| | React | 18+ | | React Hook Form | 7+ | | TypeScript | 5+ (recommended) |
License
MIT
Made with ❤️ by Thanh Se
Documentation
react-hook-form-base re-exports the complete public API of React Hook Form.
All official React Hook Form documentation, guides, examples, and tutorials are fully compatible with this package.
Simply replace:
import { useForm } from "react-hook-form";with:
import { useForm } from "react-hook-form-base";📖 React Hook Form Documentation: https://react-hook-form.com/docs
