Mae'r erthygl hon yn cael ei noddi gan SurveyJS Mae yna fodel meddwl y mae'r rhan fwyaf o ddatblygwyr React yn ei rannu heb erioed ei drafod yn uchel. Mae'r ffurflenni hynny bob amser i fod i fod yn gydrannau. Mae hyn yn golygu pentwr fel:
Ffurflen React Hook ar gyfer gwladwriaeth leol (ail-rendradau lleiaf posibl, cofrestru maes ergonomig, rhyngweithio hanfodol). Zod ar gyfer dilysu (cywirdeb mewnbwn, dilysu ffiniau, dosrannu math-diogel). Ymateb Ymholiad ar gyfer backend: cyflwyno, ail-geisio, caching, cysoni gweinydd, ac ati.
Ac ar gyfer y mwyafrif helaeth o ffurflenni - eich sgriniau mewngofnodi, eich tudalennau gosodiadau, eich moddau CRUD - mae hyn yn gweithio'n dda iawn. Mae pob darn yn gwneud ei waith, maen nhw'n cyfansoddi'n lân, a gallwch chi symud ymlaen i'r rhannau o'ch cais sy'n gwahaniaethu'ch cynnyrch mewn gwirionedd. Ond o bryd i'w gilydd, mae ffurflen yn dechrau cronni pethau fel rheolau gwelededd sy'n dibynnu ar atebion cynharach, neu werthoedd deilliedig sy'n rhaeadru trwy dri maes. Efallai hyd yn oed tudalennau cyfan y dylid eu hepgor neu eu dangos yn seiliedig ar gyfanswm rhedeg. Rydych chi'n trin yr amodol cyntaf gyda useWatch a changen unol, sy'n iawn. Yna un arall. Yna rydych chi'n estyn am superRefine i amgodio rheolau traws-faes na all eich sgema Zod eu mynegi yn y ffordd arferol. Yna, mae llywio cam yn dechrau gollwng rhesymeg busnes. Ar ryw adeg, rydych chi'n edrych ar yr hyn rydych chi wedi'i adeiladu ac yn sylweddoli nad yw'r ffurflen yn UI bellach mewn gwirionedd. Mae’n fwy o broses benderfynu, a’r goeden gydran yn union lle y digwyddoch ei storio. Dyma lle dwi’n meddwl bod y model meddyliol ar gyfer ffurflenni yn React yn chwalu, a bai neb mewn gwirionedd. Mae stac RHF + Zod yn ardderchog ar yr hyn y cafodd ei ddylunio ar ei gyfer. Y mater yw ein bod yn tueddu i barhau i'w ddefnyddio heibio'r pwynt lle mae ei dyniadau yn cyd-fynd â'r broblem oherwydd bod y dewis arall yn gofyn am ffordd wahanol o feddwl am ffurflenni yn gyfan gwbl. Mae'r erthygl hon yn ymwneud â'r dewis arall hwnnw. I ddangos hyn, byddwn yn adeiladu'r un ffurf aml-gam yn union ddwywaith:
Gyda Ffurflen Hook React + Zod wedi'i wifro i React Query i'w gyflwyno, Gyda SurveyJS, sy'n trin ffurf fel data - sgema JSON syml - yn hytrach na choeden gydran.
Yr un gofynion, yr un rhesymeg amodol, yr un alwad API ar y diwedd. Yna byddwn yn mapio’n union beth symudodd a beth arhosodd, a gosod allan ffordd ymarferol o benderfynu pa fodel y dylech ei ddefnyddio, a phryd. Y ffurflen rydyn ni'n ei hadeiladu:
Bydd y ffurflen hon yn defnyddio llif 4 cam: Cam 1: Manylion
Enw cyntaf (gofynnol), E-bost (gofynnol, fformat dilys).
Cam 2: Gorchymyn
Pris uned, Nifer, Cyfradd treth, Yn deillio: Is-gyfanswm, Treth, Cyfanswm.
Cam 3: Cyfrif ac Adborth
Oes gennych chi gyfrif? (Ie/Na) Os Oes → enw defnyddiwr + cyfrinair, mae angen y ddau. Os Na → e-bost a gasglwyd eisoes yng ngham 1.
Sgôr boddhad (1-5) Os ≥ 4 → gofynnwch “Beth oeddech chi'n ei hoffi?” Os ≤ 2 → gofynnwch “Beth allwn ni ei wella?”
Cam 4: Adolygu
Dim ond yn ymddangos os yw'r cyfanswm >= 100 Cyflwyniad terfynol.
Nid yw hyn yn eithafol. Ond mae'n ddigon i ddatgelu gwahaniaethau pensaernïol. Rhan 1: A yrrir gan Gydran (Ffurflen Adwaith Bachyn + Zod) Gosodiad npm gosod zod react-hook-form @hookform/resolvers @tanstack/react-query
Sgema Zod Gadewch i ni ddechrau gyda sgema Zod, oherwydd dyna fel arfer lle mae siâp y ffurflen yn sefydlu. Ar gyfer y ddau gam cyntaf - manylion personol a mewnbynnau archeb - mae popeth yn syml: llinynnau gofynnol, rhifau ag isafswm, ac enum. Mae'r rhan ddiddorol yn dechrau pan fyddwch chi'n ceisio mynegi'r rheolau amodol.
mewnforio { z } o "zod";
allforio const formSchema = z.object({ firstName: z.string().min(1, "Angenrheidiol"), e-bost: z.string().email("E-bost annilys"), pris: z.number().min(0), maint: z.number().min(1), taxRate: z.number(), hasAccount: z.(number(), hasAccount: z.(). cyfrinair: z.string().optional(), boddhad: z.number().min(1).max(5), positiveAdborth: z.string().optional(), improvementFeedback: z.string().optional(),}).superRefine((data, ctx) => {os (data.hasAccount === "Ie") {os (!) { os yw (!) cod enw (!) { os (!) {. "custom", path: [ "enw defnyddiwr"], neges: "Angenrheidiol" }); } os (!data.password || data.password.length < 6) { ctx.addIssue({ code: "custom", path: ["cyfrinair"], neges: "Min 6 nod" });
os (data.satisfaction >= 4 && !data.positiveFeedback) { ctx.addIssue({ code: "custom", path: ["positiveFeedback"], neges: "Rhannwch yr hyn yr oeddech yn ei hoffi" }); }
os (data.satisfaction <= 2 && !data.improvementFeedback) { ctx.addIssue({ cod: "custom", llwybr:["improvementFeedback"], message: "Dywedwch wrthym beth i'w wella" }); }});
allforio math FormData = z.infer
Sylwch fod enw defnyddiwr a chyfrinair yn cael eu teipio fel dewisol () er bod eu hangen yn amodol oherwydd bod sgema lefel math Zod yn disgrifio siâp y gwrthrych, nid y rheolau sy'n llywodraethu pan fo meysydd yn bwysig. Mae'n rhaid i'r gofyniad amodol fyw y tu mewn i superRefine, sy'n rhedeg ar ôl i'r siâp gael ei ddilysu a chael mynediad i'r gwrthrych llawn. Nid diffyg yw'r gwahaniad hwnnw; dyma'r union beth y mae'r offeryn wedi'i gynllunio ar ei gyfer: superRefine yw lle mae rhesymeg traws-faes yn mynd pan na ellir ei mynegi yn strwythur y sgema ei hun. Yr hyn sydd hefyd yn nodedig yma yw'r hyn nad yw'r sgema hwn yn ei fynegi. Nid oes ganddo unrhyw gysyniad o dudalennau, dim cysyniad o ba feysydd sy'n weladwy ar ba bwynt, a dim cysyniad o lywio. Bydd hynny i gyd yn byw yn rhywle arall. Cydran Ffurf
mewnforio { useForm, useWatch } o "react-hook-form"; mewnforio { zodResolver } o "@hookform/resolvers/zod"; mewnforio { useMutation } o "@tanstack/react-query"; mewnforio { useState, useMemo } o "React"; teipio {formSemach };
const STEPS = [ "manylion", "archeb", "cyfrif", "adolygiad"];
type OrderPayload = FormData &{ subtotal: number; treth : rhif ; cyfanswm: number };
ffwythiant allforio RHFMultiStepForm() { const [step, setStep] = useState(0);
treiglad const = useMutation({ treigladFn: async (llwyth tâl: OrderPayload) => { const res = aros nôl ("/api/orders", { dull: "POST", penawdau: { "Content-Math" : "cais/json" }, corff: JSON.stringify(llwyth cyflog), }); os (!res.ok) taflu Gwall newydd("Methwyd cyflwyno"); dychwelyd res.json(); }, });
const { cofrestru, rheoli, handleSubmit, formState: { gwallau }, } = useForm
dychwelyd (
);}Gweler y Pen SurveyJS-03-RHF [fforchog] erbyn chweched difodiant. Mae cryn dipyn yn digwydd yma, ac mae’n werth arafu i sylwi ble daeth pethau i ben.
Mae'r gwerthoedd deilliadol - is-gyfanswm, treth, cyfanswm - yn cael eu cyfrifo yn y gydran trwy useWatch a useMemo oherwydd eu bod yn dibynnu ar werthoedd maes byw ac nid oes lle naturiol arall iddynt. Mae'r rheolau gwelededd ar gyfer enw defnyddiwr, cyfrinair, Adborth cadarnhaol, ac adborth gwella yn byw yn JSX fel amodau mewnol. Mae'r rhesymeg cam-sgipio - y dudalen adolygu ond yn ymddangos pan fydd cyfanswm >= 100 - wedi'i hymgorffori yn y newidyn showSubmit a'r amod rendrad ar gam 3. Dim ond cownter useState yw llywio ei hun yr ydym yn ei gynyddu â llaw. Mae React Query yn ymdrin ag ailgeisiadau, caching, ac annilysu. Mae'r ffurflen yn galw mutation.mutate gyda data dilys.
Nid oes dim o hyn yn anghywir, fel y cyfryw. Adwaith idiomatig yw hwn o hyd, ac mae'r gydran yn eithaf perfformiwr diolch i'r modd y mae RHF yn ynysu ail-rendradau. Ond pe baech yn rhoi hwn i rywun nad oedd wedi ei ysgrifennu ac yn gofyn iddynt egluro o dan ba amodau y mae'r dudalen adolygu'n ymddangos, byddai'n rhaid iddynt olrhain trwy showSubmit, cyflwr rendrad cam 3, a rhesymeg y botwm nav - tri lle ar wahân - i ail-greu rheol y gellid bod wedi'i nodi mewn un llinell. Mae'r ffurflen yn gweithio, ydy, ond nid yw'r ymddygiad yn un y gellir ei archwilio mewn gwirionedd fel system. Mae'n rhaid ei weithredu yn feddyliol. Yn bwysicach fyth, mae angen cyfranogiad peirianyddol i'w newid. Mae hyd yn oed tweak bach, fel addasu pan fydd y cam adolygu yn ymddangos, yn golygu golygu'r gydran, diweddaru dilysiad, agor cais tynnu, aros am adolygiad, a defnyddio eto. Rhan 2: Scheme-Driver (ArolwgJS) Nawr, gadewch i ni adeiladu'r un llif gan ddefnyddio sgema. Gosodiad npm gosod survey-core survey-react-ui @tanstack/react-query
arolwg-craidd Yr injan rhedeg platfform-annibynnol â thrwydded MIT sy'n pweru rendrad ffurf SurveyJS - y rhan sy'n bwysig i ni yma. Mae'n cymryd sgema JSON, yn adeiladu model mewnol ohono, ac yn delio â phopeth a fyddai fel arall yn byw yn eich cydran React: gwerthuso ymadroddion gwelededd, cyfrifo gwerthoedd sy'n deillio, rheoli cyflwr tudalen, olrhain dilysiad, a phenderfynu beth mae “cyflawn” yn ei olygu o ystyried pa dudalennau a ddangoswyd mewn gwirionedd.
survey-react-uiThe UI / haen rendro sy'n cysylltu'r model hwnnw ag React. Yn ei hanfod mae'n gydran
Gyda'i gilydd, maent yn rhoi amser rhedeg ffurflen aml-dudalen gwbl weithredol i chi heb ysgrifennu un llinell o lif rheoli. Mae fformat y sgema ei hun, fel y dywedwyd o'r blaen, yn JSON yn unig - dim DSL nac unrhyw beth perchnogol. Gallwch ei fewnlinio, ei fewnforio o ffeil, ei nôl o API, neu ei storio mewn colofn cronfa ddata a'i hydradu ar amser rhedeg. Yr Un Ffurf, Fel Data Dyma'r un ffurf, y tro hwn wedi'i fynegi fel gwrthrych JSON. Mae'r sgema yn diffinio popeth: strwythur, dilysiad, rheolau gwelededd, cyfrifiadau deilliedig, llywio tudalennau - a'i roi i Fodel sy'n ei werthuso ar amser rhedeg. Dyma sut olwg sydd arno yn llawn:
export const surveySchema = { title: "Llif Gorchymyn", showProgressBar: "brig", tudalennau: [ { enw: "manylion", elfennau: [ { type: "text", name: "firstName", isRequired: true }, { type: "text", name: "e-bost", inputType: "email", isRequired: true, validators: [{ text: " } email " inRequired: [{ text: " } email " !name: "trethRate", defaultValue: 0.1, options: [ { value: 0.05, text: "5%" }, { value: 0.1, text: "10%" }, { value: 0.15, text: "15%" } ]}, { type: "expression", name: " subtotal " {} = " subtotal " , {} = subtotal " , {} = subtotal " , {} = subtotal " , {} = " subtotal " , {} = " subtotal " , {}} "mynegiant", name: "treth", mynegiant: " {subtotal} {taxRate}" }, { type: "mynegiant", name: "cyfanswm", mynegiant: "{ subtotal} + {treth}" } ]}, { name: "cyfrif", elfennau: [ { math: " radiogroup " , name : " has Account " , options " : " { " } enw ", hascount", choices: [ " ] { " } enw " , " , { " } enw " , " , { " } math " , " , " } enw " , " , { " } math " , dewisiadau " : " { } } math " username ", visibleIf: " {hasAccount} = 'Ie'", isRequired: true }, { type: " text " , name : " password " ", inputType: " password ", visibleIf: " {hasAccount} = 'Ie'", isRequired: true, dilyswyr: [{ type: "text", minLength: 6, texting, "MinLength: 6, text:" {} name = "MinLength: 6, text:" {}; "boddhad", rateMin: 1, rateMax: 5 }, { type: "comment", name: "positiveFeedback", visibleIf: " { bodlonrwydd } > = 4 " }, { type: " comment " , name: "improvementFeedback", visibleIf: " { bodlonrwydd} <= 2 " } ] } , {0 } review " , {0 } } , {0} } review ", {0}| elfennau: [ ] } ]};
Cymharwch hwn â fersiwn RHF am eiliad.
Mae'r bloc superRefine yr oedd angen enw defnyddiwr a chyfrinair yn amodol arno wedi diflannu. visibleIf: "{hasAccount} = 'Ie'" wedi'i gyfuno ag isRequired: mae gwir yn trin y ddau bryder gyda'i gilydd, ar y maes ei hun, lle byddech chi'n disgwyl dod o hyd iddyn nhw. Mae'r gadwyn useWatch + useMemo a gyfrifodd is-gyfanswm, treth a chyfanswm yn cael ei disodli gan dri maes mynegiant sy'n cyfeirio at ei gilydd yn ôl enw. Cyflwr y dudalen adolygu, a oedd yn y fersiwn RHF yn ail-greu dim ond trwy olrhain trwy showSubmit, y gangen rendrad cam 3. Ac yn olaf, mae'r rhesymeg botwm llywio yn briodwedd sengl visibleIf ar y gwrthrych dudalen.
Mae'r un rhesymeg yno. Dim ond bod y sgema yn rhoi lle iddo fyw lle mae'n weladwy ar ei ben ei hun, yn hytrach na'i wasgaru ar draws y gydran. Sylwch hefyd fod y sgema yn defnyddio math: 'mynegiant' ar gyfer is-gyfanswm, treth, a chyfanswm. Mae mynegiant yn ddarllen-yn-unig ac yn cael ei ddefnyddio'n bennaf i arddangos gwerthoedd wedi'u cyfrifo. Mae SurveyJS hefyd yn cefnogi math: 'html' ar gyfer cynnwys statig, ond ar gyfer gwerthoedd wedi'u cyfrifo, mynegiant yw'r dewis cywir. Nawr ar gyfer ochr React. Rendro A Chyflwyno Syml iawn. Gwifrwch onComplete i'ch API yr un ffordd - trwy useMutation neu nôl plaen:
mewnforio { useState, useEffect, useRef } o "react"; mewnforio { useMutation } o "@tanstack/react-query"; mewnforio { Model } o "survey-core"; mewnforio { Survey } o "survey-react-ui"; mewnforio "survey-core/survey-core.css";
ffwythiant allforio SurveyForm() { const [model] = useState(() => Model newydd(surveySchema));
treiglad const = useMutation({ treigladFn: async (data) => { const res = aros nôl ("/api/orders", { dull: "POST", penawdau: { "Content-Math" : "cais/json" }, corff: JSON.stringify(data), }); os (!res.ok) taflu Gwall newydd("Methwyd cyflwyno"); dychwelyd res.json(); }, });
const mutationRef = useRef(treiglad); mutationRef.current = treiglad; useEffect(() => { const handler = (anfonwr) => treigladRef.current.mutate(sender.data); model.onComplete.add(triniwr); dychwelyd () => model.onComplete.remove(triniwr); }, [model]); // cyf yn osgoi ailgofrestru triniwr pob rendrad (treiglad gwrthrych newid hunaniaeth)
dychwelyd (
<>
Gweler y Pen SurveyJS-03-SurveyJS [fforchog] erbyn chweched difodiant.
onComplete tanau pan fydd y defnyddiwr yn cyrraedd diwedd y dudalen weladwy olaf. Felly os nad yw cyfanswm byth yn croesi 100 a bod y dudalen adolygu'n cael ei hepgor, mae'n dal i danio'n gywir oherwydd bod SurveyJS yn gwerthuso gwelededd cyn penderfynu beth yw ystyr “tudalen olaf”. Yna, mae sender.data yn cynnwys yr holl atebion ynghyd â'r gwerthoedd a gyfrifwyd (is-gyfanswm, treth, cyfanswm) fel meysydd o'r radd flaenaf, felly mae llwyth tâl API yn union yr un fath â'r hyn y mae'r fersiwn RHF wedi'i ymgynnull â llaw arSubmit. Mae'rMae patrwm treigloRef yr un peth y byddech chi'n ei gyrraedd ar gyfer unrhyw le mae angen triniwr digwyddiad sefydlog arnoch chi dros werth sy'n newid ar bob rendrad - dim byd sy'n benodol i SurveyJS amdano.
Nid yw cydran React bellach yn cynnwys unrhyw resymeg busnes o gwbl. Nid oes useWatch, dim JSX amodol, dim cownter cam, dim cadwyn useMemo, dim superRefine. Mae React yn gwneud yr hyn y mae'n dda am ei wneud mewn gwirionedd: rendro cydran a'i weirio i alwad API. Beth Symudodd Allan O Adwaith?
Pryder Stack RHF ArolwgJS Gwelededd canghennau JSX gweladwyOs Gwerthoedd deilliedig useWatch / useMemo mynegiant Rheolau traws-faes superRefine Amodau sgema Mordwyo cyflwr cam Tudalen weladwyOs Lleoliad rheol Wedi'i ddosbarthu ar draws ffeiliau Wedi'i ganoli yn y sgema
Yr hyn sy'n aros yn React yw cynllun, steilio, gwifrau cyflwyno, ac integreiddio app, sef y pethau y mae React wedi'u cynllunio ar eu cyfer mewn gwirionedd. Symudodd popeth arall i'r sgema, a chan mai gwrthrych JSON yn unig yw'r sgema, gellir ei storio mewn cronfa ddata, ei fersiwn yn annibynnol o'ch cod cais, neu ei olygu trwy offer mewnol heb fod angen ei ddefnyddio. Gall rheolwr cynnyrch sydd angen newid y trothwy sy'n sbarduno'r dudalen adolygu wneud hynny heb gyffwrdd â'r gydran. Mae hynny'n wahaniaeth gweithredol ystyrlon i dimau lle mae ymddygiad ffurf yn esblygu'n aml ac nid yw bob amser yn cael ei yrru gan beirianwyr. Pryd i Ddefnyddio Pob Dull? Dyma reol fawd dda sy'n gweithio i mi: dychmygwch ddileu'r ffurflen yn gyfan gwbl. Beth fyddech chi'n ei golli?
Os mai sgriniau ydyw, rydych chi eisiau ffurflenni sy'n cael eu gyrru gan gydrannau. Os mai rhesymeg busnes, fel trothwyon, rheolau canghennog, a gofynion amodol sy'n amgodio penderfyniadau go iawn, rydych chi eisiau injan sgema.
Yn yr un modd, os yw'r newidiadau sy'n dod i'ch ffordd yn ymwneud yn bennaf â labeli, meysydd a chynllun, bydd RHF yn gwasanaethu'n iawn i chi. Os ydyn nhw'n ymwneud ag amodau, canlyniadau, a rheolau y gallai fod angen i'ch gweithredwyr neu'ch tîm cyfreithiol eu haddasu ar brynhawn dydd Mawrth heb ffeilio tocyn, y model sgema gyda SurveyJS yw'r ffit mwyaf gonest. Nid yw'r ddau ddull hyn mewn gwirionedd yn cystadlu â'i gilydd. Maent yn mynd i'r afael â gwahanol ddosbarthiadau o broblemau, a'r camgymeriad sy'n werth ei osgoi yw camgymharu'r tynnu â phwysau'r rhesymeg - trin system reolau fel cydran oherwydd dyna'r offeryn cyfarwydd, neu estyn am beiriant polisi oherwydd bod ffurf wedi tyfu i dri cham a chaffael maes amodol. Mae'r ffurf a adeiladwyd gennym yma yn eistedd ger y ffin yn fwriadol, yn ddigon cymhleth i ddatgelu'r gwahaniaeth ond nid mor eithafol fel bod y gymhariaeth yn teimlo'n anhyblyg. Mae'n debyg bod y rhan fwyaf o ffurfiau go iawn sydd wedi mynd yn anhylaw yn eich sylfaen cod yn agos at yr un ffin, a'r cwestiwn fel arfer yw a oes unrhyw un wedi enwi'r hyn ydyn nhw mewn gwirionedd. Defnyddiwch React Hook Form + Zod pan:
Mae ffurflenni yn canolbwyntio ar CRUD; Mae rhesymeg yn fas ac yn cael ei gyrru gan UI; Mae peirianwyr yn berchen ar bob ymddygiad; Mae'r ôl-ôl yn parhau i fod yn ffynhonnell gwirionedd.
Defnyddiwch SurveyJS pan:
Mae ffurflenni yn amgodio penderfyniadau busnes; Mae rheolau'n esblygu'n annibynnol ar UI; Rhaid i resymeg fod yn weladwy, yn archwiliadwy, neu'n fersiwn; Mae pobl nad ydynt yn beirianwyr yn dylanwadu ar ymddygiad; Rhaid i'r un ffurf redeg ar draws blaenau lluosog.