Skip to content

React Hook Form

React Hook Form is a popular form library for React. It is primarily designed to work directly with plain HTML input elements, but supports custom form components like the ones in @cfa/react-core as well.

Since React Core manages the state for components internally, you can use the Controller component from React Hook Form to integrate React Core components. Pass the props for the field render prop through to the React Core component you’re using, and use the fieldState to get validation errors to display.

import { useForm, Controller } from "react-hook-form";
import { Form, TextInput, Button } from "@cfa/react-core";
function App() {
let { handleSubmit, control } = useForm({
defaultValues: {
name: "",
},
});
let onSubmit = (data) => {
// Call your API here...
};
return (
<Form onSubmit={handleSubmit(onSubmit)}>
<Controller
control={control}
name="name"
rules={{ required: "Name is required." }}
render={({
field: { name, value, onChange, onBlur, ref },
fieldState: { invalid, error },
}) => (
<TextInput
label="Name"
name={name}
value={value}
onChange={onChange}
onBlur={onBlur}
ref={ref}
isRequired
validationState={invalid ? "invalid" : undefined}
errorMessage={error?.message}
/>
)}
/>
<Button type="submit" variant="primary">
Submit
</Button>
</Form>
);
}

Date and Time Fields

Date pickers use @internationalized/date objects rather than native Date. See the Dates and Times guide for the full overview. With React Hook Form, store the date value directly in your form data:

import { useForm, Controller } from "react-hook-form";
import { Form, DatePicker, Button } from "@cfa/react-core";
import { parseDate } from "@cfa/react-core/dates";
function App() {
let { handleSubmit, control } = useForm({
defaultValues: {
dob: parseDate("1990-06-15"),
},
});
let onSubmit = (data) => {
// data.dob.toString() → "1990-06-15"
};
return (
<Form onSubmit={handleSubmit(onSubmit)}>
<Controller
control={control}
name="dob"
rules={{ required: "Date of birth is required." }}
render={({ field: { value, onChange }, fieldState: { invalid, error } }) => (
<DatePicker
label="Date of Birth"
value={value}
onChange={onChange}
isRequired
isInvalid={invalid}
errorMessage={error?.message}
/>
)}
/>
<Button type="submit" variant="primary">
Submit
</Button>
</Form>
);
}