Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/rare-eels-juggle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@tanstack-isomorphic-form/core": patch
"@tanstack-isomorphic-form/react": patch
---

Allow `useIsomorphicForm(loaderData, options)` in the React package to accept hook-level `defaultValues`, using those values to seed idle form state for a specific hook instance while preserving the existing sanitizer behavior.
8 changes: 7 additions & 1 deletion libs/react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,19 @@ Represents an unexpected exception thrown while running the form action or loade
- `formDataOptions`: optional parsing delimiters for nested keys
- `returnedValueSanitizer`: optional function to normalize values stored in `formState`

### `useIsomorphicForm(loaderData)`
### `useIsomorphicForm(loaderData, options?)`

Turns loader data into:

- `formProps`: props to spread onto the `<form>`
- `formState`: reactive state representing the current form lifecycle

Hook options:

- `defaultValues`: optional initial values for this hook instance; these seed `formState.values` and take precedence over defaults passed to the loader, which themselves take precedence over defaults configured on `createIsomorphicForm`
- `onSuccess`: optional callback invoked after a successful action
- `onError`: optional callback invoked for form-level errors and unexpected failures

### `formState`

`formState.status` can be:
Expand Down
11 changes: 7 additions & 4 deletions libs/react/src/form-hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,19 @@ type IsomorphicFormHookOptions<

export const createIsomorphicFormHook =
<const TSchema extends FormDataSchema, const TActionFn extends FormAction<TSchema>>({
defaultValues,
formDataExtractor,
actionFn,
returnedValueSanitizer,
schema,
}: {
defaultValues?: InferFormDataSchemaExtract<TSchema> | undefined;
formDataExtractor: FormDataExtractor<TSchema>;
schema: TSchema;
returnedValueSanitizer?: ValueSanitizer<TSchema> | undefined;
actionFn: TActionFn;
}): IsomorphicFormHook<TSchema, TActionFn> =>
<const TActionUrl extends string>(
{ actionUrl, state }: Awaited<FormLoaderReturn<TSchema, TActionFn, TActionUrl>>,
{ onError, onSuccess }: IsomorphicFormHookOptions<TSchema, TActionFn> = {},
{ defaultValues, onError, onSuccess }: IsomorphicFormHookOptions<TSchema, TActionFn> = {},
) =>
useIsomorphicForm({
actionFn,
Expand Down Expand Up @@ -103,7 +101,12 @@ const useIsomorphicForm = <
}): IsomorphicFormHookReturn<TSchema, TActionFn, TActionUrl> => {
const navigate = useNavigate();
const [formState, setFormState] = useState(
state.status === "idle" && defaultValues ? { ...state, values: defaultValues } : state,
state.status === "idle" && defaultValues
? {
...state,
values: returnedValueSanitizer ? returnedValueSanitizer(defaultValues) : defaultValues,
}
: state,
);
const submitRef = useRef(false);

Expand Down
1 change: 0 additions & 1 deletion libs/react/src/isomorphic-form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ export const createIsomorphicForm = <
}),
useIsomorphicForm: createIsomorphicFormHook({
actionFn,
defaultValues,
formDataExtractor,
returnedValueSanitizer,
schema,
Expand Down