@next-safe-action/adapter-react-hook-form
Version:
This adapter offers a way to seamlessly integrate next-safe-action with react-hook-form.
83 lines (82 loc) • 3.69 kB
JavaScript
"use client";
import { mapToHookFormErrors } from "./index.mjs";
import { useAction, useOptimisticAction } from "next-safe-action/hooks";
import * as React from "react";
import { useForm } from "react-hook-form";
//#region src/hooks.ts
/**
* For more advanced use cases where you want full customization of the hooks used, you can
* use this hook to map a validation errors object to a `FieldErrors` compatible with react-hook-form.
* You can then pass the returned `hookFormValidationErrors` property to `useForm`'s `errors` prop.
*
* @param validationErrors Validation errors object from `next-safe-action`
* @returns Object of `FieldErrors` compatible with react-hook-form
*/
function useHookFormActionErrorMapper(validationErrors, props) {
const joinBy = props?.joinBy;
return { hookFormValidationErrors: React.useMemo(() => mapToHookFormErrors(validationErrors, joinBy !== void 0 ? { joinBy } : void 0), [validationErrors, joinBy]) };
}
/**
* Internal helper that wires up a safe action result with react-hook-form.
* Extracts the common logic shared by `useHookFormAction` and `useHookFormOptimisticAction`.
*/
function useFormIntegration(action, hookFormResolver, props) {
const { hookFormValidationErrors } = useHookFormActionErrorMapper(action.result.validationErrors, props?.errorMapProps);
const form = useForm({
...props?.formProps,
resolver: hookFormResolver,
errors: hookFormValidationErrors
});
const { handleSubmit, reset: resetForm } = form;
const { executeAsync, reset: resetAction } = action;
return {
form,
handleSubmitWithAction: React.useCallback((e) => handleSubmit(executeAsync)(e), [handleSubmit, executeAsync]),
resetFormAndAction: React.useCallback(() => {
resetForm();
resetAction();
}, [resetForm, resetAction])
};
}
/**
* This hook is a wrapper around `useAction` and `useForm` that makes it easier to use safe actions
* with react-hook-form. It also maps validation errors to `FieldErrors` compatible with react-hook-form.
*
* @param safeAction The safe action
* @param hookFormResolver A react-hook-form validation resolver
* @param props Optional props for both `useAction`, `useForm` hooks and error mapper
* @returns An object containing `action` and `form` controllers, `handleSubmitWithAction`, and `resetFormAndAction`
*/
function useHookFormAction(safeAction, hookFormResolver, props) {
const action = useAction(safeAction, props?.actionProps);
const { form, handleSubmitWithAction, resetFormAndAction } = useFormIntegration(action, hookFormResolver, props);
return {
action,
form,
handleSubmitWithAction,
resetFormAndAction
};
}
/**
* This hook is a wrapper around `useOptimisticAction` and `useForm` that makes it easier to use safe actions
* with react-hook-form. It also maps validation errors to `FieldErrors` compatible with react-hook-form.
*
* @param safeAction The safe action
* @param hookFormResolver A react-hook-form validation resolver
* @param props Required `currentState` and `updateFn` props for the action, and additional optional
* props for both `useAction`, `useForm` hooks and error mapper
* @returns An object containing `action` and `form` controllers, `handleSubmitWithAction`, and `resetFormAndAction`
*/
function useHookFormOptimisticAction(safeAction, hookFormResolver, props) {
const action = useOptimisticAction(safeAction, props.actionProps);
const { form, handleSubmitWithAction, resetFormAndAction } = useFormIntegration(action, hookFormResolver, props);
return {
action,
form,
handleSubmitWithAction,
resetFormAndAction
};
}
//#endregion
export { useHookFormAction, useHookFormActionErrorMapper, useHookFormOptimisticAction };
//# sourceMappingURL=hooks.mjs.map