Как создать многоэтапную форму в NextJS с помощью @tanstack/formJavascript

Форум по Javascript
Ответить
Anonymous
 Как создать многоэтапную форму в NextJS с помощью @tanstack/form

Сообщение Anonymous »

Недавно я перенес свой проект с реакции-хука-формы (rhf) на @tanstack/form и по большей части мне очень понравилась реализация. Одна проблема, с которой я столкнулся и не могу найти решение, — это многоэтапная форма. Моя текущая реализация использует хранилище zustand и делает каждый шаг формы отдельной формой, которая сохраняет данные в хранилище и переходит к следующему шагу. Если пользователь находится на последнем шаге, форма отправит все собранные данные. Проблема, с которой я столкнулся, заключается в том, что каждый шаг представляет собой, по сути, один и тот же код, за исключением функции отправки и значений по умолчанию, которые не очень СУХИЕ. Попытка создать многоразовый компонент шага формы не представляется возможной с помощью @tanstack/form. Это пример одного раздела:
// schema.ts

import { z } from "zod";

const communicationSettingsSchema = z.object({
emailCommunications: z.boolean(),
emailUpdates: z.boolean(),
});

export type CommunicationSettingsSchema = z.infer;

const communicationSettingsSchemaDefaultValues: CommunicationSettingsSchema = {
emailCommunications: true,
emailUpdates: false,
};

export { communicationSettingsSchema, communicationSettingsSchemaDefaultValues };


// component.tsx

"use client";

import { EllipsisVerticalIcon } from "lucide-react";
import * as z from "zod";

import { Button } from "@/components/ui/button";
import { Field, FieldDescription, FieldLabel } from "@/components/ui/field";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Switch } from "@/components/ui/switch";

import {
FormSection,
FormSectionContent,
FormSectionDescription,
FormSectionHeader,
FormSectionTitle,
} from "@/features/settings/components/form-section";
import { COMMUNICATION_SECTION as section } from "@/features/settings/constants";
import {
communicationSettingsSchemaDefaultValues as defaultValues,
communicationSettingsSchema as schema,
} from "@/features/settings/schemas";
import { useOnboardingStepsStore } from "@/features/settings/stores/use-onboarding-steps-store";

import { sleep } from "@/utils/sleep";

import { useAppForm } from "@/hooks/forms";

type Props = {
step: number;
};

function OnboardingFormCommunicationSection({ step }: Props) {
// store actions
const currentStep = useOnboardingStepsStore((state) => state.currentStep);

// store actions
const setPreviousStep = useOnboardingStepsStore((state) => state.setPreviousStep);
const setSettings = useOnboardingStepsStore((state) => state.setSettings);
const setActiveSteps = useOnboardingStepsStore((state) => state.setActiveSteps);
const setNextStep = useOnboardingStepsStore((state) => state.setNextStep);

// form methods
const form = useAppForm({
defaultValues,
validators: { onSubmit: schema },
onSubmit: async ({ value }) => {
// simulate async operation
await sleep({ ms: 150 });

// update store preferences
setSettings(value);

// mark the next step available
setActiveSteps(2);

setNextStep();
},
});

if (step === currentStep)
return (
{
e.preventDefault();
form.handleSubmit();
}}
>


{section.title}
{section.description}


{section.settings.map((setting) => {
return (

{(field) => {
const isInvalid = field.state.meta.isTouched && !field.state.meta.isValid;

return (


field.handleChange(Boolean(v))}
aria-invalid={isInvalid}
/>



{setting.fieldLabel}

{setting.fieldDescription}








{setting.helperText}





);
}}

);
})}



setPreviousStep()}
disabled={currentStep === 1}
>
Prev






);
}

export { OnboardingFormCommunicationSection };

Я хотел бы создать компонент, который позволит мне передавать форму следующим образом:
const Example = () => {
// form
const form = useAppForm({
defaultValues,
validators: { onSubmit: schema },
onSubmit: async ({ value }) => {
console.log(value);
},
});

return
};

export { Example };


Подробнее здесь: https://stackoverflow.com/questions/798 ... stack-form
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»