Multi-STEP Form React Hook Form Press Представляет значения последнего шага-как сохранить и отправить все значения шага?Javascript

Форум по Javascript
Ответить Пред. темаСлед. тема
Anonymous
 Multi-STEP Form React Hook Form Press Представляет значения последнего шага-как сохранить и отправить все значения шага?

Сообщение Anonymous »

I'm building a reusable form component in React that supports both:
  • Simple (single-step) forms, and
  • Multi-step forms (each step has its own schema and inputs).
I'm using:
  • react-hook-form
  • zod для проверки схемы
  • Компоненты пользовательских оберток, такие как FormWrapper , Rhfinput
Проблема:


< /ul>
rhfinput.tsx
import {
forwardRef,
memo,
type Ref,
type RefCallback,
type RefObject,
} from "react";
import { useFormContext, type FieldValues, type Path } from "react-hook-form";
import {
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";

type RHFInputProps = {
name: Path;
label?: string;
placeholder?: string;
type?: string;
disabled?: boolean;
};

function mergeRefs(...refs: (Ref | undefined)[]): RefCallback {
return (value: T) => {
refs.forEach((ref) => {
if (typeof ref === "function") {
ref(value);
} else if (ref && typeof ref === "object") {
(ref as RefObject).current = value;
}
});
};
}

// 1. Define generic component WITHOUT forwardRef:
function RHFInputInner(
{ name, label, placeholder, type = "text", disabled }: RHFInputProps,
ref: Ref
) {
const { control } = useFormContext();

return (
{
const { ref: fieldRef, ...restField } = field;
return (

{label && {label}}






);
}}
/>
);
}

const RHFInput = forwardRef(RHFInputInner) as (
props: RHFInputProps & { ref?: Ref }
) => React.ReactElement;

export default memo(RHFInput);
< /code>
formwrapper.tsx
import type { ReactNode } from "react";
import type {
DefaultValues,
FieldValues,
SubmitHandler,
UseFormProps,
UseFormReturn,
} from "react-hook-form";
import { ZodSchema, ZodType } from "zod";

export type FormContext =
UseFormReturn & {
readOnly: boolean;
};

export type FormStep = {
schema: ZodType;
content: React.ReactNode;
};

export interface FormWrapperProps {
isMultiStep?: boolean;
mode?: UseFormProps["mode"];
readOnly?: boolean;
defaultValues?: DefaultValues;
children?: ReactNode;
onSubmit: SubmitHandler;
steps?: FormStep[];
submitLabel?: string;
schema: ZodSchema;
className?: string;
}

import { memo, useCallback, useState } from "react";
import { isEqual } from "lodash";
import { FormProvider, useForm, type FieldValues } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { cn } from "@/lib/utils";
import { Form } from "@/components/ui/form";
import { Button } from "@/components/ui/button";

const FormWrapper = ({
isMultiStep,
mode = "all",
readOnly = false,
defaultValues,
onSubmit,
steps,
submitLabel = "Submit",
schema,
children,
className,
}: FormWrapperProps) => {
const [step, setStep] = useState(0);
const currentStep = isMultiStep ? steps?.[step] : undefined;

const currentSchema = isMultiStep ? steps?.[step]?.schema ?? schema : schema;
const methods = useForm({
mode,
defaultValues,
resolver: zodResolver(currentSchema),
});

const extendedForm: FormContext = {
...methods,
readOnly,
};

const handleNext = useCallback(async () => {
const valid = await methods.trigger();
if (!valid) return;

setStep((prev) => Math.min(prev + 1, (steps?.length ?? 1) - 1));
}, [methods, steps]);

const handlePrev = useCallback(() => {
setStep((prev) => Math.max(prev - 1, 0));
}, []);

const handleFinalSubmit = useCallback(
(data: T) => {
onSubmit(data);
},
[onSubmit]
);

const isFirstStep = step === 0;
const isLastStep = step === (steps?.length ?? 1) - 1;
const canGoNext = !isLastStep;
const canGoPrev = !isFirstStep;

return (



{isMultiStep ? currentStep?.content : children}
{isMultiStep ? (
className={cn(
"flex items-center w-full",
canGoPrev ? "justify-between" : "justify-end"
)}
>

{canGoPrev && (

Prev

)}

{canGoNext ? (

Next

) : (
{submitLabel}
)}


) : (

{submitLabel}

)}



);
};

export default memo(FormWrapper, isEqual);
< /code>
userpage.tsx
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import FormWrapper from "@/components/form/form-wrapper";

import RHFInput from "@/components/form/controller/RHFInput";
import { z } from "zod";
import type { FormStep } from "@/components/form/types";

const step1Schema = z.object({
name: z.string().min(1, "Name is required"),
});
const step2Schema = z.object({
email: z.string().email("Invalid email"),
});

const mergedSchema = step1Schema.merge(step2Schema);

type FormType = z.infer

const steps: FormStep[] = [
{
schema: step1Schema,
content: (

),
},
{
schema: step2Schema,
content: (

),
},
];

const UserPage = () => {
return (


Create Plan



Create New Plan


console.log("Submitted data", data)}
isMultiStep
steps={steps}
>




);
};

export default UserPage;


Подробнее здесь: https://stackoverflow.com/questions/796 ... to-preserv
Реклама
Ответить Пред. темаСлед. тема

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

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

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

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

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Multi-STEP Form React Hook Form Press Представляет значения последнего шага-как сохранить и отправить все значения шага?
    Anonymous » » в форуме Javascript
    0 Ответы
    2 Просмотры
    Последнее сообщение Anonymous
  • Selenium - Multi Browser и Multi User Log
    Anonymous » » в форуме JAVA
    0 Ответы
    12 Просмотры
    Последнее сообщение Anonymous
  • Multi-Role/Multianant Auth: Laravel Multi-Role/Multianant Auth: Customer Login Plound (проблема сеанса/промежуточного пр
    Anonymous » » в форуме Php
    0 Ответы
    6 Просмотры
    Последнее сообщение Anonymous
  • Multi-Role/Multianant Auth: Laravel Multi-Role/Multianant Auth: Customer Login Plound (проблема сеанса/промежуточного пр
    Anonymous » » в форуме Php
    0 Ответы
    5 Просмотры
    Последнее сообщение Anonymous
  • Multi-Role/Multianant Auth: Laravel Multi-Role/Multianant Auth: Customer Login Plound (проблема сеанса/промежуточного пр
    Anonymous » » в форуме Php
    0 Ответы
    6 Просмотры
    Последнее сообщение Anonymous

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