Nkan yii jẹ onigbọwọ nipasẹ SurveyJS Awoṣe opolo kan wa pupọ julọ awọn olupilẹṣẹ React pin laisi jiroro rẹ rara. Awọn fọọmu yẹn nigbagbogbo yẹ lati jẹ awọn paati. Eyi tumọ si akopọ bi:

Fọọmu kio fesi fun ipinlẹ agbegbe (awọn atunṣe ti o kere ju, iforukọsilẹ aaye ergonomic, ibaraenisepo pataki). Zod fun afọwọsi (atunse igbewọle, afọwọsi aala, iru-itupalẹ ailewu). Ibeere fesi fun ẹhin: ifakalẹ, awọn igbiyanju, caching, amuṣiṣẹpọ olupin, ati bẹbẹ lọ.

Ati fun ọpọlọpọ awọn fọọmu - awọn iboju iwọle rẹ, awọn oju-iwe eto rẹ, awọn awoṣe CRUD rẹ - eyi ṣiṣẹ daradara gaan. Ẹyọ kọọkan n ṣe iṣẹ rẹ, wọn ṣajọ ni mimọ, ati pe o le lọ si awọn apakan ti ohun elo rẹ ti o ṣe iyatọ ọja rẹ gaan. Ṣugbọn ni gbogbo igba ni igba diẹ, fọọmu kan bẹrẹ ikojọpọ awọn nkan bii awọn ofin hihan ti o dale lori awọn idahun iṣaaju, tabi awọn iye ti a mu jade ti o ka nipasẹ awọn aaye mẹta. Boya paapaa gbogbo awọn oju-iwe ti o yẹ ki o fo tabi han da lori apapọ nṣiṣẹ. O mu ipo akọkọ pẹlu useWatch ati ẹka inline, eyiti o dara. Lẹhinna miiran. Lẹhinna o n de ọdọ SuperRefine lati ṣe koodu awọn ofin aaye-agbelebu ti eto Zod rẹ ko le ṣalaye ni ọna deede. Lẹhinna, lilọ kiri ni igbesẹ bẹrẹ jijo ọgbọn iṣowo. Ni aaye kan, o wo ohun ti o ti kọ ati rii pe fọọmu naa kii ṣe UI gaan mọ. O jẹ diẹ sii ti ilana ipinnu, ati igi paati jẹ o kan nibiti o ti ṣẹlẹ lati tọju rẹ. Eyi ni ibiti Mo ro pe awoṣe ọpọlọ fun awọn fọọmu ni React fọ, ati pe kii ṣe ẹbi gaan. Iṣakojọpọ RHF + Zod dara julọ ni ohun ti o ṣe apẹrẹ fun. Ọrọ naa ni pe a ṣọ lati tọju lilo rẹ kọja aaye nibiti awọn abstractions rẹ baamu iṣoro naa nitori yiyan nilo ọna ti o yatọ ti ironu nipa awọn fọọmu patapata. Nkan yii jẹ nipa yiyan yẹn. Lati ṣe afihan eyi, a yoo kọ fọọmu-igbesẹ pupọ kanna ni ẹẹmeji:

Pẹlu Fọọmu Hook React + Zod ti firanṣẹ lati Ibeere Idahun fun ifakalẹ, Pẹlu SurveyJS, eyiti o tọju fọọmu kan bi data - ero JSON ti o rọrun - kuku ju igi paati kan.

Awọn ibeere kanna, ọgbọn ipo kanna, ipe API kanna ni ipari. Lẹhinna a yoo ya aworan gangan ohun ti o gbe ati ohun ti o duro, ati ṣeto ọna ti o wulo lati pinnu iru awoṣe ti o yẹ ki o lo, ati nigbawo. Fọọmu ti a n kọ:

Fọọmu yii yoo lo sisan-igbesẹ mẹrin: Igbesẹ 1: Awọn alaye

Orukọ akọkọ (beere fun), Imeeli (beere, ọna kika to wulo).

Igbesẹ 2: Paṣẹ

Iye owo ẹyọkan, Iwọn, Oṣuwọn owo-ori, Ti ari: Lapapọ, Owo-ori, Lapapọ.

Igbesẹ 3: Akọọlẹ & Esi

Ṣe o ni akọọlẹ kan? (Bẹẹni/Bẹẹkọ) Ti Bẹẹni → orukọ olumulo + ọrọ igbaniwọle, mejeeji nilo. Ti Bẹẹkọ → imeeli ti gba tẹlẹ ni igbesẹ 1.

Iwọn itelorun (1-5) Ti ≥ 4 → beere "Kini o fẹran?" Ti ≤ 2 → beere “Kini a le mu dara si?”

Igbesẹ 4: Atunwo

Nikan han ti lapapọ>=100 Ifakalẹ ipari.

Eyi kii ṣe iwọn. Ṣugbọn o to lati ṣafihan awọn iyatọ ti ayaworan. Apá 1: Ìwakọ paati (Fọọmu Hook Fesi + Zod) Fifi sori ẹrọ npm fi sori ẹrọ react-hook-form zod @hookform/resolvers @tanstack/react-query

Eto Zod Jẹ ki a bẹrẹ pẹlu eto Zod, nitori pe igbagbogbo ni ibi ti apẹrẹ ti fọọmu naa ti fi idi mulẹ. Fun awọn igbesẹ meji akọkọ - awọn alaye ti ara ẹni ati awọn igbewọle aṣẹ - ohun gbogbo jẹ taara: awọn okun ti a beere, awọn nọmba pẹlu awọn o kere ju, ati enum kan. Awọn awon apakan bẹrẹ nigbati o ba gbiyanju lati han ni àídájú awọn ofin.

gbe wọle {z} lati "zod";

okeere const formSchema = z.ohun ({ firstName: z.string () z.string ().iyan (), ọrọigbaniwọle: z.string ().iyan (), itelorun: z.number () .min (1) .max (5), positiveFeedback: z.string () .iyan (), ilọsiwajuFeedback: z.string ().iyan (),}).superRefine ((data, ctx) => {ti o ba ti (data.hasAccount) {==" orukọ === "data. ctx.addIssue ({koodu: "aṣa", ọna: ["orukọ olumulo"], ifiranṣẹ: "Ti beere" });

ti (data.satisfaction >= 4 && !data.positiveFeedback) {ctx.addIssue ({koodu: "aṣa", ọna: ["positiveFeedback"], ifiranṣẹ: "Jọwọ pin ohun ti o fẹran"}); }

ti (data.satisfaction <= 2 && !data.improvementFeedback) {ctx.addIssue({koodu: "aṣa", ọna:["improvementFeedback"], ifiranṣẹ: "Jọwọ sọ fun wa kini lati ṣe ilọsiwaju"}); }});

okeere iru FormData = z.infer;

Ṣe akiyesi pe orukọ olumulo ati ọrọ igbaniwọle ti wa ni titẹ bi iyan () botilẹjẹpe wọn nilo ni majemu nitori eto iru-ipele Zod ṣe apejuwe apẹrẹ ohun naa, kii ṣe awọn ofin ti n ṣakoso nigbati awọn aaye ṣe pataki. Ibeere majemu ni lati gbe inu superRefine, eyiti o ṣiṣẹ lẹhin apẹrẹ ti a fọwọsi ati ni iwọle si ohun kikun. Iyapa yẹn kii ṣe abawọn; o kan jẹ ohun ti a ṣe apẹrẹ ọpa fun: superRefine ni ibi ti ọgbọn-aaye agbelebu n lọ nigbati ko le ṣe afihan ni eto eto ara rẹ. Ohun ti o tun ṣe akiyesi nibi ni ohun ti ero yii ko ṣalaye. Ko ni ero ti awọn oju-iwe, ko si imọran ti awọn aaye wo ni o han ni aaye wo, ko si si imọran ti lilọ kiri. Gbogbo eyi yoo gbe ni ibomiiran. Ẹya Fọọmu

gbe wọle {useForm, useWatch} lati "react-hook-form"; gbe wọle {zodResolver} lati "@hookform/resolvers/zod"; gbe wọle {useMutation } lati "@tanstack/react-query"; gbe wọle {useState, useMemo } lati "react"/gbewọle; gbe wọle Fun "formSchema,}

const STEPS = ["alaye", "ibere", "iroyin", "atunyẹwo"];

iru OrderPayload = FormData & {subtotal: nọmba; ori: nọmba; lapapọ: nọmba};

iṣẹ okeere RHFMultiStepForm () {const [igbesẹ, setStep] = useState (0);

const iyipada = lilo iyipada ({ iyipadaFn: async (ẹrù isanwo: OrderPayload) => { const res = duro de ("/api/orders", { ọna: "POST", awọn akọle: {"Akoonu-Iru": "application/json" }, ara: JSON.stringify (payload), }); ti o ba ti (!res.ok) jabọ titun aṣiṣe ("Kuna lati fi"); pada res.json (); }, });

const {forukọsilẹ, iṣakoso, handleSubmit, formState: {aṣiṣe },} = useForm({ resolver: zodResolver(formSchema), defaultValues: { price: 0, quantity: 1, taxRate: 0.1, satisfaction: 3, hasAccount: "Brara",}); idiyele const = useWatch ({iṣakoso, orukọ: "owo"}); const quantity = useWatch ({iṣakoso, orukọ: "opoiye"}); const taxRate = useWatch ({iṣakoso, orukọ: "TaxRate"}); const hasAccount = useWatch ({iṣakoso, orukọ: "hasAccount"}); const itelorun = useWatch ({iṣakoso, orukọ: "itẹlọrun"}); const subtotal = useMemo(() => (iye ?? 0) * (oye ?? 1), [iye, opoiye]); const ori = useMemo(() => subtotal * (oṣuwọn owo-ori ?? 0), [subtotal, taxRate]); const lapapọ = useMemo(() => subtotal + ori, [subtotal, ori]); const onSubmit = (data: FormData) => mutation.mutate ({...data, subtotal, ori, lapapọ}); const showSubmit = (igbese === 2 && lapapọ <100) || (igbese === 3 && lapapọ >= 100)

pada ( {igbese === 0 && ( <> )}

{igbese === 1 && ( <> otitọ", {: iye = " 0.05 " >5% 10% 15%

Subtotal: {subtotal}
Tax: {ori}
Lapapọ: {lapapọ}
)}

{igbese === 2 && ( <>

{hasAccount === "Bẹẹni" && ( <> )}

{ itelorun >= 4 && (