React Hook Form Resolver
If you use React Hook Form, this package now ships a dedicated resolver adapter as a separate subpath export:
import { useForm } from 'react-hook-form'
import { createSchema } from 'json-rest-schema'
import { jsonRestSchemaResolver } from 'json-rest-schema/react-hook-form'That import path is intentional. The resolver lives outside the main schema engine so the core library does not become React-specific.
Basic usage
const profileSchema = createSchema({
name: { type: 'string', required: true, minLength: 3 },
role: { type: 'string', defaultTo: 'guest' }
})
const form = useForm({
resolver: jsonRestSchemaResolver(profileSchema)
})By default, the resolver uses create semantics for full-form validation.
That means:
- required fields are enforced
- defaults are applied on successful full-form validation
- the resolver itself returns normalized success values for full-form validation
So if the user submits:
{
name: ' Alex '
}the resolver will hand React Hook Form a successful value object equivalent to:
{
name: 'Alex',
role: 'guest'
}One real-world nuance matters here: React Hook Form still owns its internal field state. In practice, that means a successful resolver pass does not always mean your submit handler receives a canonical normalized payload directly from RHF's state.
If you need a final REST-ready payload, run one last schema operation in the submit handler:
const form = useForm({
resolver: jsonRestSchemaResolver(profileSchema)
})
const onSubmit = rawValues => {
const { validatedObject, errors } = profileSchema.create(rawValues)
if (Object.keys(errors).length > 0) return
saveProfile(validatedObject)
}That split is intentional:
- RHF keeps raw interactive field state
- the schema owns final normalization at the submit boundary
- the UI is free to avoid aggressive value rewriting while the user is typing
Edit forms and custom operations
If the form is editing an existing resource, use a different operation explicitly.
For a patch-style form:
const form = useForm({
resolver: jsonRestSchemaResolver(profileSchema, {
operation: 'patch'
})
})You can also use any custom operation you have registered on the schema:
const form = useForm({
resolver: jsonRestSchemaResolver(profileSchema, {
operation: 'upsert'
})
})Field-level re-validation behavior
React Hook Form re-validates one field at a time during user interaction. The resolver uses the core path APIs for that subset validation.
Important behavior:
- only the selected RHF field names are validated during field-level re-validation
- sibling required fields do not leak into a single-field re-validation pass
- by default, field-level re-validation keeps raw form values instead of forcing normalized values back into the UI while the user is typing
That default matters because aggressive normalization during typing can feel bad:
- trimmed strings can move the cursor
- number coercion can fight half-complete input
- defaults can appear before submit
Opting into normalized field-level values
If you explicitly want normalized field values during field-level re-validation, opt in:
const form = useForm({
resolver: jsonRestSchemaResolver(
profileSchema,
{},
{ normalizeOnFieldValidation: true }
)
})This is opt-in on purpose.
Returning raw values on success
If you want successful resolver results to return raw input values instead of normalized values, use raw: true:
const form = useForm({
resolver: jsonRestSchemaResolver(
profileSchema,
{},
{ raw: true }
)
})That applies to successful full-form validation too, so defaults and casts are not pushed into the returned values object.
Error shape
React Hook Form requires hierarchical nested errors for deep paths. The resolver converts the library's flat dotted-path errors into the structure RHF expects.
For example, a schema error like:
{
'roles.0.label': {
field: 'roles.0.label',
code: 'REQUIRED',
message: 'Field is required',
params: {}
}
}becomes a React Hook Form error shape equivalent to:
{
roles: [
{
label: {
type: 'REQUIRED',
message: 'Field is required'
}
}
]
}Direct array-field errors are placed under RHF's root key for that field array path.
Native browser validation
The resolver also respects React Hook Form's shouldUseNativeValidation option. If RHF asks for native validation, the adapter sets setCustomValidity() / reportValidity() using the schema error messages.