Lesi sihloko sixhaswe ngabakwa-SurveyJS Kunemodeli yengqondo iningi lonjiniyela be-React ababelana ngayo ngaphandle kokuxoxa ngayo ngokuzwakalayo. Lawo mafomu ngaso sonke isikhathi kufanele abe izingxenye. Lokhu kusho isitaki esifana nalokhu:

I-React Hook Form yesifunda sendawo (ukunikezwa kabusha okuncane, ukubhaliswa kwenkambu ye-ergonomic, ukusebenzisana okubalulekile). I-Zod yokuqinisekisa (ukulunga kokokufaka, ukuqinisekiswa komngcele, ukuhlukanisa okuphephile kohlobo). Umbuzo we-React for backend: ukuhambisa, ukuzama futhi, ukulondoloza isikhashana, ukuvumelanisa iseva, nokunye.

Futhi ngobuningi bamafomu - izikrini zakho zokungena ngemvume, amakhasi akho ezilungiselelo, amamodeli akho e-CRUD - lokhu kusebenza kahle kakhulu. Ucezu ngalunye lwenza umsebenzi walo, lubhala ngokuhlanzekile, futhi ungadlulela ezingxenyeni zohlelo lwakho lokusebenza ezihlukanisa ngempela umkhiqizo wakho. Kodwa njalo ngemva kwesikhathi esithile, ifomu liqala ukuqongelela izinto ezifana nemithetho yokubonakala encike ezimpendulweni zangaphambili, noma amanani atholiwe adlula ezinkambini ezintathu. Mhlawumbe nawo wonke amakhasi okufanele eqiwe noma aboniswe ngokusekelwe enanini elisebenzayo. Uphatha imibandela yokuqala nge-useWatch kanye negatsha elisemgqeni, lokho kulungile. Bese kuba omunye. Ngemuva kwalokho usufinyelela ku-superRefine ukuze ufake ikhodi yemithetho ye-cross-field schema sakho se-Zod esingakwazi ukuyiveza ngendlela evamile. Bese, ukuzulazula kwesinyathelo kuqala ukuvuza ingqondo yebhizinisi. Kwesinye isikhathi, ubheka lokho okwakhile bese ubona ukuthi ifomu ayiseyona i-UI ngempela. Kuyinqubo yesinqumo, futhi ingxenye yesihlahla yilapho nje wenze khona ukuthi uyigcine. Kulapho ngicabanga ukuthi imodeli yengqondo yamafomu ku-React ibhidlika, futhi empeleni akulona iphutha likabani. Isitaki se-RHF + Zod sihle kakhulu kulokho ebesiklanyelwe kona. Inkinga ukuthi sivame ukuqhubeka nokuyisebenzisa kudlule iphuzu lapho izifinyezo zayo zihambisana nenkinga ngoba enye idinga indlela ehlukile yokucabanga ngamafomu ngokuphelele. Lesi sihloko simayelana nalokho okunye. Ukukhombisa lokhu, sizokwakha ifomu elifanayo lezinyathelo eziningi kabili:

Nge-React Hook Form + i-Zod enentambo yokuphendula Umbuzo ukuze uthunyelwe, Nge-SurveyJS, ephatha ifomu njengedatha - i-schema ye-JSON elula - kunengxenye yesihlahla.

Izidingo ezifanayo, ingqondo enemibandela efanayo, ikholi ye-API efanayo ekugcineni. Ngemuva kwalokho sizobe sibeka imephu kahle ukuthi yini ehambile nokuthi yini eyasala, bese sibeka indlela esebenzayo yokunquma ukuthi iyiphi imodeli okufanele uyisebenzise, ​​futhi nini. Ifomu esilakhayo:

Leli fomu lizosebenzisa ukugeleza okuyizinyathelo ezi-4: Isinyathelo 1: Imininingwane

Igama lokuqala (kuyadingeka), I-imeyili (edingekayo, ifomethi evumelekile).

Isinyathelo sesi-2: Oda

Intengo yeyunithi, Ubuningi, Izinga lentela, Kuthathwe: Isamba esiphelele, Intela, Ingqikithi.

Isinyathelo sesi-3: I-akhawunti nempendulo

Ingabe unayo i-akhawunti? (Yebo/Cha) Uma Yebo → igama lomsebenzisi + nephasiwedi, kokubili kuyadingeka. Uma Cha → i-imeyili isiqoqwe kakade esinyathelweni 1.

Isilinganiso sokwaneliseka (1–5) Uma ≥ 4 → buza “Yini oyithandile?” Uma ≤ 2 → buza “Yini esingayithuthukisa?”

Isinyathelo sesi-4: Buyekeza

Ivela kuphela uma ingqikithi >= 100 Ukuthunyelwa kokugcina.

Lokhu akukhona okweqisayo. Kodwa kwanele ukuveza umehluko wezakhiwo. Ingxenye 1: I-Component-Driven (I-React Hook Form + Zod) Ukufakwa npm faka i-react-hook-form zod @hookform/resolvers @tanstack/react-query

Zod Schema Ake siqale nge-schema ye-Zod, ngoba imvamisa yilapho ukwakheka kwefomu kusungulwa khona. Ezinyathelweni ezimbili zokuqala - imininingwane yomuntu siqu kanye nokokufaka kwe-oda - yonke into iqondile: izintambo ezidingekayo, izinombolo ezinobuncane, kanye ne-enum. Ingxenye ethokozisayo iqala lapho uzama ukuveza imithetho enemibandela.

ngenisa {z } kusuka ku-"zod";

thekelisa i-const formSchema = z.object({ firstName: z.string().min(1, "Kudingeka"), i-imeyili: z.string().i-imeyili("I-imeyili engavumelekile"), intengo: z.number().min(0), ubuningi: z.number().min(1), IntelaRate: z.number(), z.Yescount:Acnum" igama lomsebenzisi,Inombolo:YesNumber: z.string().ongakukhetha(), iphasiwedi: z.string().ongakukhetha(), ukwaneliseka: z.number().min(1).max(5), positiveFeedback: z.string().optional(), improvementFeedback: z.string().optional(),}).superRefine((data, ctx) => {if (data) =Yeus =Year (data.=Ames) = {ctx.addIssue({code: "custom", indlela: ["igama lomsebenzisi"], umlayezo: "Kuyadingeka" }} uma (!data.password || data.password.length < 6) {ctx.addIssue({code: "custom", path: ["password"]); umlayezo: "}}}

uma (data.satisfaction >= 4 && !data.positiveFeedback) {ctx.addIssue({code: "custom", path: ["positiveFeedback"], umlayezo: "Sicela wabelane ngokuthandile" }); }

uma (data.satisfaction <= 2 && !data.improvementFeedback) {ctx.addIssue({ code: "custom", indlela:["improvementFeedback"], umlayezo: "Sicela usitshele ukuthi sithuthukise ini" }); }});

thekelisa uhlobo FormData = z.infer;

Qaphela ukuthi igama lomsebenzisi nephasiwedi kuthayiphiwe njengokukhetha() noma kudingekile ngokwemibandela ngoba i-schema yezinga le-Zod sichaza umumo wento, hhayi imithetho ebusa lapho izinkambu zibalulekile. Imfuneko enemibandela kufanele iphile ngaphakathi kwe-superRefine, esebenza ngemva kokuba umumo uqinisekisiwe futhi ukwazi ukufinyelela entweni egcwele. Lokho kuhlukana akulona iphutha; yilokho nje ithuluzi eliklanyelwe kona: i-superRefine yilapho ingqondo ye-cross-field logic iya khona lapho ingakwazi ukuvezwa kusakhiwo se-schema ngokwayo. Okunye okuphawulekayo lapha ukuthi lesi schema esingakuvezi. Ayinawo umqondo wamakhasi, akukho mqondo wokuthi yiziphi izinkambu ezibonakala lapho, futhi akukho mqondo wokuzulazula. Konke lokho kuyohlala kwenye indawo. Ingxenye Yefomu

ngenisa i-{useForm, useWatch } isuka ku-"react-hook-form";ngenisa i-{zodResolver } isuka ku-"@hookform/resolvers/zod";ngenisa {useMutation } isuka ku-"@tanstack/react-query";ngenisa {useState, useMemo } kusukela ku-"react";ngenisa {formSchema} kusuka ku-"Daschema";

const IZINYATHELO = ["imininingwane", "oda", "i-akhawunti", "buyekeza"];

thayipha i-OrderPayload = I-FormData & {ingqikithi encane: inombolo; intela: inombolo; inani: inombolo };

umsebenzi wokuthekelisa RHFMultiStepForm() { const [isinyathelo, setStep] = useState(0);

Const mutation = useMutation ({ mutationFn: async (payload: OrderPayload) => { const res = lindela ukulanda("/api/oda", { indlela: "THUMELA", izihloko: { "Content-Type": "application/json" }, umzimba: JSON.stringify(payload), }); uma (!res.ok) ephonsa Iphutha elisha("Yehlulekile ukuhambisa"); buyisela res.json(); }, });

const {rejista, lawula, phathaSubmit, formState: { errors }, } = useForm({solver: zodResolver(formSchema), defaultValues: { price: 0, quantity: 1, taxRate: 0.1, satisfaction: 3, hasAccount: "Cha);", },}} const price = useWatch({ control, name: "price" }); const quantity = useWatch({ control, name: "quantity" }); const taxRate = useWatch({ control, name: "taxRate" }); const hasAccount = useWatch({ control, name: "hasAccount" }); const satisfaction = useWatch({ control, name: "ukwaneliseka" }); const subtotal = useMemo(() => (inani ?? 0) * (inani ?? 1), [inani, inani]); const tax = useMemo(() => inani eliphansi * (Inani lentela ?? 0), [isamba esingaphansi, Isilinganiso sentela]); const total = useMemo(() => inani eliphansi + intela, [isamba esingaphansi, intela]); const onSubmit = (idatha: FormData) => mutation.mutate({ ...data, subtotal, tax, total }); const showSubmit = (isinyathelo === 2 && inani <100) || (isinyathelo === 3 && isamba >= 100)

buyisela (

{step === 0 && ( <> )}

{step === 1 && ( <>

Isamba esingaphansi: {subtotal}
Intela: {tax}
Ingqikithi: {total}
)}

{step === 2 && ( <>

{hasAccount === "Yebo" && ( <> )}

{satisfaction >= 4 && (