Tanstack Form + React Router 7? #1686
Unanswered
dominik-stagtech
asked this question in
Q&A
Replies: 2 comments 2 replies
-
|
wondering the same thing. Not loving conform for more complex cases. |
Beta Was this translation helpful? Give feedback.
0 replies
-
|
After mucking about with some of the out of date / incomplete examples in the docs, I came up with this minimal working example of how to use Tanstack form With React Router framework mode import type { Route } from './+types/route';
import { z } from 'zod';
import {
ServerValidateError,
createServerValidate,
formOptions,
initialFormState,
useForm,
useTransform,
mergeForm,
} from '@tanstack/react-form-remix';
import { Form, useSubmit } from 'react-router';
const exampleSchema = z.object({
age: z.number().gte(10, 'Age must be greater than 10'),
firstName: z.string().min(1, 'Name is required'),
});
export const formOpts = formOptions({
defaultValues: {
firstName: '',
age: 0,
},
validators: {
onSubmit: exampleSchema,
},
});
const serverValidate = createServerValidate({
...formOpts,
onServerValidate: ({ value }) => {},
});
export async function action({ request }: Route.ActionArgs) {
const formData = await request.formData();
try {
const validatedData = await serverValidate(formData);
/* validated data is typed 🙂 */
console.log('validatedData', validatedData);
} catch (e) {
if (e instanceof ServerValidateError) {
return e.formState;
}
throw e;
}
}
export default function MyTanstackFormRouteComponent({
actionData,
}: Route.ComponentProps) {
const submit = useSubmit();
const form = useForm({
...formOpts,
onSubmit: (args) => submit(args.value, { method: 'POST' }),
transform: useTransform(
(baseForm) => mergeForm(baseForm, actionData ?? initialFormState),
[actionData],
),
});
console.log(form.state);
return (
<div className="relative overflow-hidden slide-card">
<Form navigate={false} onSubmit={form.handleSubmit}>
<form.Field name="age">
{(field) => {
return (
<div>
<input
name="age"
type="number"
value={field.state.value}
onChange={(e) => field.handleChange(e.target.valueAsNumber)}
/>
{field.state.meta.errors.map((error) => (
/* these are actually zod errors 🙂 */
<p key={error?.message}>{error?.message}</p>
))}
</div>
);
}}
</form.Field>
<form.Field name="firstName">
{(field) => {
return (
<div>
<input
name="firstName"
type="text"
value={field.state.value}
onChange={(e) => field.handleChange(e.target.value)}
/>
{field.state.meta.errors.map((error) => (
/* these are actually zod errors 🙂 */
<p key={error?.message}>{error?.message}</p>
))}
</div>
);
}}
</form.Field>
<form.Subscribe
selector={(formState) => [
formState.canSubmit,
formState.isSubmitting,
]}
>
{([canSubmit, isSubmitting]) => (
<button type="submit" disabled={!canSubmit}>
{isSubmitting ? '...' : 'Submit'}
</button>
)}
</form.Subscribe>
</Form>
</div>
);
} |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Has anyone used this successfully with React Router 7? We have a project that uses RR7 in framework mode and I am really curious if Tanstack Form is a good alternative to Conform here.
I couldn't find anything online about the combination of these two, all I could find were examples for Remix. Is "@tanstack/react-form/remix" still a thing and is it compatible with RR7?
Beta Was this translation helpful? Give feedback.
All reactions