Tá an t-alt seo urraithe ag SurveyJS Tá múnla meabhrach ann a roinneann an chuid is mó d’fhorbróirí React gan é a phlé os ard riamh. Go bhfuil foirmeacha ceaptha i gcónaí a bheith comhpháirteanna. Ciallaíonn sé seo cruach mar:

Foirm Hook React don stát áitiúil (ath-rindreáil íosta, clárú réimse eirgeanamaíochta, idirghníomhú riachtanach). Zod le haghaidh bailíochtaithe (cirt ionchuir, bailíochtú teorann, parsáil cineál-sábháilte). Freagair Iarratas le haghaidh inneall: aighneacht, atriail, taisceadh, sioncronú freastalaí, agus mar sin de.

Agus d'fhormhór mór na bhfoirmeacha - do scáileáin logála isteach, do leathanaigh socruithe, do mhodhanna CRUD - oibríonn sé seo go han-mhaith. Déanann gach píosa a chuid oibre, cumann siad go glan, agus is féidir leat bogadh ar aghaidh go dtí na codanna de d'iarratas a dhéanann idirdhealú iarbhír ar do tháirge. Ach ó am go chéile, tosaíonn foirm ag carnadh rudaí cosúil le rialacha infheictheachta a bhraitheann ar fhreagraí níos luaithe, nó luachanna díorthaithe a ritheann trí réimse. B'fhéidir fiú leathanaigh iomlána ar chóir iad a scipeáil nó a thaispeáint bunaithe ar iomlán reatha. Láimhseálann tú an chéad choinníoll le useWatch agus brainse inlíne, atá ceart go leor. Ansin eile. Ansin tá tú ag iarraidh superRefine chun rialacha tras-réimse a ionchódú nach féidir le do scéimre Zod a chur in iúl ar an ngnáthbhealach. Ansin, tosaíonn loingseoireacht céim ag sceitheadh ​​​​loighic ghnó. Ag pointe éigin, breathnaíonn tú ar a bhfuil tógtha agat agus tuigeann tú nach UI i ndáiríre an fhoirm a thuilleadh. Is próiseas cinnteoireachta níos mó é, agus is é an crann comhpháirte díreach an áit ar tharla duit é a stóráil. Seo an áit ar dóigh liom go mbrisfidh an tsamhail mheabhrach le haghaidh foirmeacha in React, agus níl an locht ar éinne i ndáiríre. Tá an chairn RHF + Zod ar fheabhas ar an méid a dearadh dó. Is í an tsaincheist ná go bhfuil sé de nós againn leanúint ar aghaidh ag baint úsáide as an bpointe go bhfuil a astarraingtí ag teacht leis an bhfadhb mar go dteastaíonn bealach eile chun smaoineamh ar fhoirmeacha ina n-iomláine. Baineann an t-alt seo leis an rogha eile sin. Chun é seo a thaispeáint, tógfaimid an fhoirm ilchéime chéanna faoi dhó:

Le Foirm Hook React + Zod sreangaithe chun Iarratas a Fhrithghníomh le cur isteach, Le SurveyJS, a dhéileálann le foirm mar shonraí - scéimre JSON simplí - seachas crann comhpháirte.

Ceanglais chéanna, loighic choinníollach céanna, glao API céanna ag an deireadh. Ansin léarscáileoimid go díreach cad a athraíodh agus cad a d’fhan, agus leagfaimid amach bealach praiticiúil chun cinneadh a dhéanamh maidir leis an múnla ba chóir duit a úsáid, agus cathain. An fhoirm atá á tógáil againn:

Úsáidfidh an fhoirm seo sreabhadh 4 chéim: Céim 1: Sonraí

Céadainm (riachtanach), Ríomhphost (riachtanach, formáid bhailí).

Céim 2: Ordú

Praghas aonaid, Cainníocht, Ráta cánach, Díorthaithe: Fo-iomlán, Cáin, Iomlán.

Céim 3: Cuntas & Aiseolas

An bhfuil cuntas agat? (Tá/Níl) Má tá → ainm úsáideora + pasfhocal, tá an dá cheann ag teastáil. Mura bhfuil → ríomhphost bailithe cheana féin i gcéim 1.

Rátáil sásaimh (1–5) Má ≥ 4 → fiafraigh “Cad a thaitin leat?” Má ≤ 2 → fiafraigh “Cad is féidir linn a fheabhsú?”

Céim 4: Athbhreithniú

Ní fheictear ach amháin más é iomlán >= 100 é Aighneacht deiridh.

Níl sé seo an-mhór. Ach is leor é chun difríochtaí ailtireachta a nochtadh. Cuid 1: Comhpháirt-tiomáinte (React Hook Foirm + Zod) Suiteáil npm suiteáil react-hook-form zod @hookform/resolvers @tanstack/react-query

Scéimre Zod Tosaímid leis an scéimre Zod, mar is iondúil gur sin a bhunaítear cruth na foirme. Don chéad dá chéim - sonraí pearsanta agus ionchuir ordaithe - tá gach rud simplí: teaghráin riachtanacha, uimhreacha le híosmhéideanna, agus enum. Tosaíonn an chuid suimiúil nuair a dhéanann tú iarracht na rialacha coinníollach a chur in iúl.

allmhairiú { z } ó "zod";

export const formSchema = z.object({ firstName: z.string().min(1, "Riachtanach"), r-phost: z.string().email("Ríomhphost neamhbhailí"), praghas: z.number().min(0), cainníocht: z.number().min(1), Ráta cánach: z.number(), hasAccount: z.() , , , hasCuntas: z.(op.), (": op.), ([" Ystring) "), ["string name) ), ([" Ystring) "), [" Ystring ("]): pasfhocal: z.string().roghnach(), sásamh: z.number().min(1).max(5), positiveAiseolas: z.string().optional(), improvementFeedback: z.string().roghnach(),}).superRefine((sonraí, ctx) => {más rud é (data.hasAccount === "Tá") {if (!) {más rud é (data.hasAccount === "Tá") { if (!) { . "saincheaptha", cosán: [ "ainm úsáideora"], teachtaireacht: "Riachtanach" }); } más rud é (! data.password || data.password.length < 6) { ctx.addIssue({ cód: "saincheaptha", cosán: ["focal faire"], teachtaireacht: "Íosmhéid 6 carachtair" });

más rud é (data.satisfaction >= 4 && !data.positiveFeedback) { ctx.addIssue({ cód: "custom", cosán: ["dearfachAiseolas"], teachtaireacht: "Comhroinn cad a thaitin leat" }); }

más rud é (data.satisfaction <= 2 && !data.improvementFeedback) { ctx.addIssue({ cód: "saincheaptha", cosán:["feabhsúAiseolas"], teachtaireacht: "Inis dúinn cad ba cheart a fheabhsú" }); }});

cineál easpórtála FormData = z.infer ;

Tabhair faoi deara go bhfuil an t-ainm úsáideora agus an pasfhocal clóscríofa mar roghnach() cé go bhfuil gá coinníollach leo toisc go gcuireann scéimre cineál-leibhéal Zod síos ar chruth an ruda, ní ar na rialacha a rialaíonn nuair a bhíonn réimsí tábhachtach. Caithfidh an riachtanas coinníollach maireachtáil taobh istigh de superRefine, a ritheann tar éis an cruth a bhailíochtú agus a bhfuil rochtain aige ar an réad iomlán. Ní locht é an scaradh sin; níl ann ach cad chuige a bhfuil an uirlis deartha: is é superRefine an áit a dtéann loighic tras-réimse nuair nach féidir é a chur in iúl sa struchtúr scéimre féin. Rud atá suntasach anseo freisin ná an rud nach gcuireann an scéimre seo in iúl. Níl aon choincheap leathanaigh ann, níl aon choincheap ann faoi na réimsí atá le feiceáil ag an bpointe sin, agus níl aon choincheap loingseoireachta ann. Beidh sé sin go léir beo áit éigin eile. Comhpháirt Fhoirm

iompórtáil { useForm, useWatch } ó "react-hook-form"; allmhairiú { zodResolver } ó "@hookform/resolvers/zod"; allmhairiú { useMutation } ó "@tanstack/react-query"; allmhairiú { useState, useMemo } ó "React"; cineál iompórtáil {formatSemach };

const STEPS = [ "mionsonraí", "ordú", "cuntas", "athbhreithniú"];

type OrderPayload = FormData &{ subtotal: uimhir; cáin: uimhir; iomlán: uimhir };

feidhm easpórtála RHFMultiStepForm() { const [step, setStep] = useState(0);

const mutation = useMutation({ mutationFn: async (pálasta: OrderPayload) => { const res = ag fanacht le fetch ("/api/orduithe", { modh: "POST", ceanntásca: { "Content-Type": "iarratas/json" }, comhlacht: JSON.stringify(pálasta), }); má (!res.ok) caith Earráid nua ("Theip ar chur isteach"); ais res.json(); }, });

const { clárú, rialú, láimhseáilSubmit, formState: { earráidí }, } = úsáidForm ({ réiteach: zodResolver(formSchema), Luachanna réamhshocraithe: { praghas: 0, cainníocht: 1, Ráta cánach: 0.1, sásamh: 3, tá Cuntas: "Níl", }, }); const price = useWatch({ rialú, ainm: "praghas" ​​}); const quantity = useWatch({ rialú, ainm: "cainníocht" }); const taxRate = useWatch({ rialú, ainm: "Ráta cánach" }); const hasAccount = useWatch({ rialú, ainm: "hasAccount" }); const sásamh = useWatch({ rialú, ainm: "sásamh" }); const subtotal = useMemo(() => (praghas ?? 0) * (cainníocht ?? 1), [praghas, cainníocht]); const tax = useMemo(() => fo-iomlán * (Ráta cánach ?? 0), [fo-iomlán, Ráta cánach]); const total = useMemo(() => fo-iomlán + cáin, [fo-iomlán, cáin]); const onSubmit = (sonraí: FormData) => mutation.mutate({ ...sonraí, fo-iomlán, cáin, iomlán }); const showSubmit = (céim === 2 && iomlán < 100) || (céim === 3 && iomlán >= 100)

ar ais (

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

{step === 1 && ( <> 5%

Fo-iomlán: {subtotal}
Cáin: {tax}
Iomlán: {total}
)}

{step === 2 && ( <> )

{hasAccount === "Tá" && ( <> )}

{sásamh >= 4 && (