Released in the 2020's summer, @hookform/resolvers is an optional module that allows you to validate React Hook Form's values with your favorite validation library. So far, we support 5 validation libraries: Yup, Zod, Vest, Joi, and Superstruct.
V2 summary
- π React Hook Form V7
- π¦ Compliant bundles: CommonJS, ESM & UMD
- β¨ Async/sync validation
- π Faster validation: validate only changed fields
- π Manage errored fields
- ππ»ββοΈ Reduce package size
React Hook Form V7
Recently, we announced the V7 of React Hook Form, if you haven't read it you can have a look here: What's coming in React Hook Form - Version 7
The new resolver API is based on the React Hook Form's V7 architecture. This results in resolver getting power lifted with the new options
param.
- resolver: (values: any, context?: object) => Promise<ResolverResult> | ResolverResult
+ resolver: (
+ values: any,
+ context: object | undefined,
+ options: {
+ criteriaMode?: 'firstError' | 'all',
+ names?: string[],
+ fields: { [name]: Field } // Support nested fields
+ }
+ ) => Promise<ResolverResult> | ResolverResult
The options
argument will enable developers to write better custom logic:
- optimize your schema validation with field-level validation
- have better insight on which field is getting validated
- custom focus management
Compliant bundles: CommonJS, ESM & UMD
This is probably one of the biggest challenges that we have been facing. Our issues board is pretty much occupied with related issues.
The issue is related to our module output that cannot satisfy both CommonJs and ESM format. To solve this problem, we had a couple of options on the table:
- Split into multiple packages
- Convert into a single module
However, all of them do comes with drawbacks, whether in terms of build, developer experience, or simply performance. To solve these issues, I have been heavily inspired by the Preact's work on how to ship their packages. We are using the exports
field which satisfies all bundle formats.
In the meanwhile, we have been running the beta
for a few months now and it hasn't triggered any issues, which is great news!
Resolvers imports example:
import { yupResolver }Β from "@hookform/resolvers/yup";
import { zodResolver }Β from "@hookform/resolvers/zod";
import { vestResolver }Β from "@hookform/resolvers/vest";
import { joiResolver }Β from "@hookform/resolvers/joi";
import { superstructResolver }Β from "@hookform/resolvers/superstruct";
Async/Sync validation
One of the most asked features is to be able to choose how to validate values: asynchronous
or synchronous
validation.
We made it possible In the V2, this can be achieved by passing the mode option:
function MyComponent() {
useForm({
resolver: zodResolver(schema, schemaOptions, { mode: 'sync' })
});
return (
// ...
)
}
async
is the default mode. The validation mode depends on the validationβs library used. See the compatibility table below:
Library | Async | Sync |
---|---|---|
Yup | β | β |
Zod | β | β |
Joi | β | β |
Vest | β | β |
Superstruct | β | β |
Faster validation: validate only changed fields
The new resolver will enable you to validate only changed fields. This can be achieved by making a custom resolver and improve validation time in a relatively large form. You can achieve that by using a library like Vest.
The new third argument of resolver looks like that:
{
criteriaMode?: 'firstError' | 'all',
names?: string[],
fields: { [name]: Field } // Support nested fields
}
A basic custom resolver example:
Custom focus management
Accessibility is an important aspect of a form validation library, and we are taking focus management as one of the priorities. For example, the user will automatically get focused on an error input during submit. However, there is not much room for users to customize that focus behavior, and here is the change that we made in resolvers to give you control on how and when to focus a particular input. We believe that exposing the ref
to the end-users will give them the freedom on focus management.
Reduce package size
We care about performance and package size so much, that every byte counts. The V2 is going to lose some weight! We worked and optimized each resolver to reduce their bundle size. Here is the great result:
Library | Async | New size |
---|---|---|
Yup resolver | -23% | 541 B |
Zod resolver | -28% | 467 B |
Joi resolver | -25% | 525 B |
Vest resolver | -46% | 419 B |
Superstruct resolver | -75% | 269 B |
Conclusion
I hope you all enjoy the change and improvement that we have baked into the new resolvers and looking forward to the future for more improvements over the library.
Install and try that new version:
npm install react-hook-form@beta @hookform/resolvers@beta
The repository url: https://github.com/react-hook-form/resolvers
Thanks
- All the React Hook Form team
- To bluebill1049 for the help to write that blog post
- All the contributors
β€οΈ Thank you for backing and sponsoring the project
Top comments (0)