Dan l-artikolu huwa sponsorjat minn SurveyJS Hemm mudell mentali li ħafna mill-iżviluppaturi React jaqsmu mingħajr ma qatt jiddiskutuh b'leħen għoli. Li l-formoli dejjem suppost ikunu komponenti. Dan ifisser munzell bħal:
React Hook Form għall-istat lokali (re-renders minimi, reġistrazzjoni ergonomika tal-kamp, interazzjoni imperattiva). Zod għall-validazzjoni (korrettezza tad-dħul, validazzjoni tal-konfini, parsing sigur tat-tip). Irreaġixxi Mistoqsija għal backend: sottomissjoni, provi mill-ġdid, caching, sinkronizzazzjoni tas-server, eċċ.
U għall-maġġoranza vasta tal-formoli — l-iskrins tal-login tiegħek, il-paġni tas-settings tiegħek, il-modals CRUD tiegħek — dan jaħdem tajjeb ħafna. Kull biċċa tagħmel xogħolha, huma jikkomponu b'mod nadif, u tista 'timxi fuq il-partijiet tal-applikazzjoni tiegħek li fil-fatt jiddifferenzjaw il-prodott tiegħek. Iżda kull darba, formola tibda takkumula affarijiet bħal regoli tal-viżibilità li jiddependu fuq tweġibiet preċedenti, jew valuri derivati li jgħaddu minn tliet oqsma. Forsi anke paġni sħaħ li għandhom jinqabżu jew jintwerew ibbażati fuq total kurrenti. Int timmaniġġja l-ewwel kondizzjonali b'useWatch u fergħa inline, li hija tajba. Imbagħad ieħor. Imbagħad int qed tilħaq għal superRefine biex tikkodifika regoli bejn il-kampijiet li l-iskema Zod tiegħek ma tistax tesprimi bil-mod normali. Imbagħad, in-navigazzjoni tal-pass tibda tnixxi l-loġika tan-negozju. F'xi punt, tħares lejn dak li bnejt u tirrealizza li l-formola m'għadhiex verament UI. Huwa aktar proċess ta 'deċiżjoni, u s-siġra tal-komponenti hija eżatt fejn ġara li taħżenha. Dan huwa fejn naħseb li l-mudell mentali għall-formoli f'React jkisser, u huwa verament tort ta 'ħadd. Il-munzell RHF + Zod huwa eċċellenti għal dak li kien iddisinjat għalih. Il-kwistjoni hija li għandna t-tendenza li nibqgħu nużawha wara l-punt fejn l-astrazzjonijiet tagħha jaqblu mal-problema minħabba li l-alternattiva teħtieġ mod differenti ta 'ħsieb dwar il-forom għal kollox. Dan l-artikolu huwa dwar dik l-alternattiva. Biex nuru dan, aħna ser nibnu l-istess formola f'diversi stadji eżatt darbtejn:
Bil-Formola React Hook + Zod bil-fili biex React Query għas-sottomissjoni, Ma' SurveyJS, li jittratta formola bħala data — skema JSON sempliċi — aktar milli siġra tal-komponenti.
L-istess rekwiżiti, l-istess loġika kondizzjonali, l-istess sejħa API fl-aħħar. Imbagħad aħna nimmappaw eżattament dak li ċaqlaq u dak li baqa’, u nistabbilixxu mod prattiku biex niddeċiedu liema mudell għandek tuża, u meta. Il-formola li qed nibnu:
Din il-formola se tuża fluss f'4 passi: Pass 1: Dettalji
L-isem (meħtieġa), Email (meħtieġa, format validu).
Pass 2: Ordna
Prezz unitarju, Kwantità, Rata tat-taxxa, Derivat: Subtotal, Taxxa, Total.
Pass 3: Kont u Feedback
Għandek kont? (Iva/Le) Jekk Iva → username + password, it-tnejn meħtieġa. Jekk Le → email diġà miġbura fil-pass 1.
Klassifikazzjoni ta' sodisfazzjon (1–5) Jekk ≥ 4 → staqsi “X’għoġbok?” Jekk ≤ 2 → staqsi “X’nistgħu ntejbu?”
Pass 4: Reviżjoni
Jidher biss jekk totali >= 100 Sottomissjoni finali.
Dan mhux estrem. Iżda huwa biżżejjed li tesponi d-differenzi arkitettoniċi. Parti 1: Immexxi mill-Komponent (Formola ta' Reazzjoni tal-Hook + Zod) Installazzjoni npm install react-hook-form zod @hookform/resolvers @tanstack/react-query
Skema Zod Ejja nibdew bl-iskema Zod, għaliex normalment huwa fejn il-forma tal-forma tiġi stabbilita. Għall-ewwel żewġ passi — dettalji personali u inputs tal-ordnijiet — kollox huwa sempliċi: kordi meħtieġa, numri b'minimi, u enum. Il-parti interessanti tibda meta tipprova tesprimi r-regoli kundizzjonali.
importazzjoni { z } minn "zod";
export const formSchema = z.object({ firstName: z.string().min(1, "Meħtieġa"), email: z.string().email("Invalid email"), price: z.number().min(0), kwantità: z.number().min(1), taxRate: z.number(), hasAccount: "["]), enname: z.string().optional(), password: z.string().optional(), sodisfazzjon: z.number().min(1).max(5), positiveFeedback: z.string().optional(), improvementFeedback: z.string().optional(),}).superRefine((data, ctx) => {jekk (data, ctx) => {jekk (data) . ctx.addIssue({ code: "custom", path: ["username"], message: "Meħtieġ" }); } if (!data.password || data.password.length < 6) { ctx.addIssue({ code: "custom", path: ["password"], messaġġ: "Min 6 karattri}"});
jekk (data.satisfaction >= 4 && !data.positiveFeedback) { ctx.addIssue({ code: "custom", path: ["positiveFeedback"], message: "Jekk jogħġbok aqsam dak li għoġobt" }); }
jekk (data.satisfaction <= 2 && !data.improvementFeedback) { ctx.addIssue ({ kodiċi: "custom", mogħdija:["improvementFeedback"], message: "Jekk jogħġbok għidilna x'għandna ntejbu"}); }});
tip ta' esportazzjoni FormData = z.infer
Innota li l-isem tal-utent u l-password huma ttajpjati bħala fakultattivi () anki jekk huma meħtieġa kondizzjonalment minħabba li l-iskema tal-livell tat-tip ta 'Zod tiddeskrivi l-għamla tal-oġġett, mhux ir-regoli li jirregolaw meta l-oqsma huma importanti. Ir-rekwiżit kondizzjonali għandu jgħix ġewwa superRefine, li jibda wara li l-forma tiġi vvalidata u jkollha aċċess għall-oġġett sħiħ. Dik is-separazzjoni mhix difett; huwa biss għalxiex l-għodda hija ddisinjata: superRefine hija fejn tmur il-loġika cross-field meta ma tistax tiġi espressa fl-istruttura tal-iskema nnifisha. Dak li huwa wkoll notevoli hawnhekk huwa dak li din l-iskema ma tesprimix. M'għandha l-ebda kunċett ta 'paġni, l-ebda kunċett ta' liema oqsma huma viżibbli f'liema punt, u l-ebda kunċett ta 'navigazzjoni. Dan kollu se jgħix x'imkien ieħor. Komponent tal-Formola
importazzjoni { useForm, useWatch } minn "react-hook-form";importazzjoni { zodResolver } minn "@hookform/resolvers/zod";importazzjoni { useMutation } minn "@tanstack/react-query";importazzjoni {useState, useMemo } minn "react";import {formSchema, tip "Form./resolver"};
const STEPS = ["dettalji", "ordni", "kont", "reviżjoni"];
tip OrderPayload = FormData & { subtotal: numru; taxxa: numru; total: numru };
funzjoni ta' esportazzjoni RHFMultiStepForm () { const [step, setStep] = useState (0);
const mutation = useMutation ({ mutationFn: async (tagħbija: OrderPayload) => { const res = stenna fetch ("/api/ordnijiet", { metodu: "POST", headers: { "Content-Type": "application/json" }, korp: JSON.stringify (tagħbija), }); if (!res.ok) throw Error ġdid ("Falla milli tissottometti"); ritorn res.json (); }, });
const { register, control, handleSubmit, formState: { żbalji }, } = useForm
return (
);}Ara l-Pen SurveyJS-03-RHF [forked] minn sixthextinction. Hawn qed iseħħu ħafna ħafna, u ta’ min jonqos biex jinduna fejn spiċċaw l-affarijiet.
Il-valuri derivati - subtotal, taxxa, totali - huma kkalkulati fil-komponent permezz ta 'useWatch u useMemo minħabba li jiddependu fuq il-valuri tal-kamp ħajjin u m'hemm l-ebda post naturali ieħor għalihom. Ir-regoli tal-viżibilità għall-isem tal-utent, il-password, positiveFeedback, u improvementFeedback jgħixu f'JSX bħala kondizzjonali inline. Il-loġika tal-pass-skipping — il-paġna tar-reviżjoni tidher biss meta totali >= 100 — hija inkorporata fil-varjabbli showSubmit u l-kundizzjoni tar-rendi fuq il-pass 3. In-navigazzjoni nnifisha hija biss counter useState li qed inżidu manwalment. React Query jimmaniġġja provi mill-ġdid, caching, u invalidazzjoni. Il-formola titlob biss mutation.mutate b'dejta validata.
Xejn minn dan mhu ħażin, per se. Dan għadu React idjomatiku, u l-komponent huwa pjuttost performant grazzi għal kif RHF jiżola mill-ġdid jirrendi. Imma kieku kellek tgħaddi dan lil xi ħadd li ma kienx kitbuha u titlobhom jispjegaw taħt liema kundizzjonijiet tidher il-paġna ta’ reviżjoni, huma jkollhom jintraċċaw permezz ta’ showSubmit, il-kundizzjoni tar-rendi tal-pass 3, u l-loġika tal-buttuna tan-nav — tliet postijiet separati — biex jibnu mill-ġdid regola li setgħet ġiet iddikjarata f’linja waħda. Il-forma taħdem, iva, iżda l-imġieba mhix verament spezzjonabbli bħala sistema. Għandu jiġi esegwit mentalment. Aktar importanti minn hekk, il-bidla teħtieġ l-involviment tal-inġinerija. Anke tweak żgħir, bħall-aġġustament meta jidher il-pass tar-reviżjoni, ifisser editjar tal-komponent, aġġornament tal-validazzjoni, ftuħ ta 'talba għall-ġibda, stennija għal reviżjoni, u skjerament mill-ġdid. Parti 2: Immexxi minn Skema (SurveyJS) Issa ejja nibnu l-istess fluss billi tuża schema. Installazzjoni npm install survey-core survey-react-ui @tanstack/react-query
survey-coreIl-magna runtime indipendenti mill-pjattaforma liċenzjata mill-MIT li tagħti s-setgħa lill-għoti tal-forma ta’ SurveyJS — il-parti li nieħdu ħsiebha hawn. Tieħu skema JSON, tibni mudell intern minnha, u tieħu ħsieb dak kollu li kieku kien jgħix fil-komponent React tiegħek: evalwazzjoni tal-espressjonijiet ta 'viżibilità, komputazzjoni ta' valuri derivati, ġestjoni tal-istat tal-paġna, validazzjoni tat-traċċar, u deċiżjoni dwar xi tfisser "kompleta" meta wieħed iqis liema paġni kienu attwalment murija.
survey-react-uiIs-saff tal-UI / rendering li jgħaqqad dak il-mudell ma' React. Huwa essenzjalment komponent
Flimkien, jagħtuk runtime tal-forma b'ħafna paġni kompletament funzjonali mingħajr ma tikteb linja waħda ta 'fluss ta' kontroll. Il-format ta 'skema innifsu huwa, kif intqal qabel, biss JSON - l-ebda DSL jew xi ħaġa proprjetarja. Tista 'taħżenha, timportaha minn fajl, ġġibha minn API, jew taħżenha f'kolonna tad-database u idratha waqt ir-runtime. L-Istess Formola, Bħala Data Hawn l-istess forma, din id-darba espressa bħala oġġett JSON. L-iskema tiddefinixxi kollox: l-istruttura, il-validazzjoni, ir-regoli tal-viżibilità, il-kalkoli derivati, in-navigazzjoni tal-paġna - u tgħaddiha lil Mudell li jevalwah waqt ir-runtime. Hawn kif tidher b'mod sħiħ:
export const surveySchema = { title: "Ordni Flow", showProgressBar: "top", paġni: [ { name: "dettalji", elementi: [ { type: "test", name: "firstName", isRequired: true }, { type: "test", name: "email", inputType: "email", isRequired: true, validators: [{ type: "email], validi: "] isem: "ordni", elementi: [ { tip: "test", isem: "prezz", inputType: "numru", defaultValue: 0}, { type: "test", isem: "kwantità", inputType: "numru", defaultValue: 1}, { type: "dropdown",isem: "taxRate", defaultValue: 0.1, għażliet: [ { valur: 0.05, test: "5%" }, { valur: 0.1, test: "10%" }, { valur: 0.15, test: "15%" } ] }, { tip: "espressjoni", isem: "subtotal", espressjoni}, {isem: {{"price", espressjoni}, {name:}"" espressjoni} "taxxa", espressjoni: "{subtotal} {taxRate}" }, { tip: "espressjoni", isem: "total", espressjoni: "{subtotal} + {taxxa}" } ] }, { isem: "kont", elementi: [ { tip: "radjugrupp", isem: "hasAccount", għażliet: ["Iva", "Le" "] }, isem, {:::" isem "us" }, {::::: "{hasAccount} = 'Iva'", isRequired: vera }, { type: "test", isem: "password", inputType: "password", visibleIf: "{hasAccount} = 'Iva'", isRequired: vera, validators: [{ type: "test", minLength: 6, text: "Min 6 karattri}," {}: ", ismijiet, ismijiet rateMin: 1, rateMax: 5 }, { tip: "kumment", isem: "positiveFeedback", visibleIf: "{sodisfazzjon} >= 4" }, { type: "kumment", name: "improvementFeedback", visibleIf: "{sodisfazzjon} <= 2" } ] }, {}: >= "review" }, {name: >: "{0} elementi viżibbli: >: "review" [] } ]};
Qabbel dan mal-verżjoni RHF għal mument.
Il-blokka superRefine li l-username u l-password meħtieġa kondizzjonalment spiċċaw. visibleIf: "{hasAccount} = 'Iva'" flimkien ma' isRequired: true jieħu ħsieb iż-żewġ tħassib flimkien, fuq il-qasam innifsu, fejn tistenna li ssibhom. Il-katina useWatch + useMemo li kkalkulat is-subtotal, it-taxxa u t-total hija sostitwita bi tliet oqsma ta' espressjoni li jirreferu lil xulxin bl-isem. Il-kundizzjoni tal-paġna ta 'reviżjoni, li fil-verżjoni RHF kienet rikostitwibbli biss billi tiġi traċċata permezz ta' showSubmit, il-fergħa tar-rendi tal-pass 3. U finalment, il-loġika tal-buttuna tan-nav hija proprjetà waħda viżibbliIf fuq l-oġġett tal-paġna.
L-istess loġika hemm. Huwa biss li l-iskema tagħtiha post fejn tgħix fejn tkun viżibbli f'iżolament, aktar milli mifruxa mal-komponent. Ukoll, innota li l-iskema tuża tip: 'espressjoni' għal subtotal, taxxa, u totali. L-espressjoni hija tinqara biss u tintuża prinċipalment biex turi valuri kkalkulati. SurveyJS jappoġġja wkoll it-tip: 'html' għal kontenut statiku, iżda għal valuri kkalkulati, l-espressjoni hija l-għażla t-tajba. Issa għan-naħa React. Rendiment U Sottomissjoni Sempliċi ħafna. Wire onComplete mal-API tiegħek bl-istess mod — permezz ta' useMutation jew sempliċi fetch:
importazzjoni { useState, useEffect, useRef } minn "react";importazzjoni { useMutation } minn "@tanstack/react-query";importazzjoni { Mudell } minn "survey-core";importazzjoni { Survey } minn "survey-react-ui";importazzjoni "survey-core/survey-core.css";
funzjoni ta 'esportazzjoni SurveyForm () { const [mudell] = useState (() => Mudell ġdid (surveySchema));
const mutation = useMutation ({ mutationFn: async (data) => { const res = stenna fetch ("/api/ordnijiet", { metodu: "POST", headers: { "Content-Type": "application/json" }, korp: JSON.stringify(data), }); if (!res.ok) throw Error ġdid ("Falla milli tissottometti"); ritorn res.json (); }, });
const mutationRef = useRef (mutazzjoni); mutationRef.current = mutazzjoni; useEffect (() => { const handler = (mittent) => mutationRef.current.mutate (sender.data); model.onComplete.add (handler); return () => model.onComplete.remove (handler); }, [mudell]); // ref jevita li jerġa' jirreġistra l-handler kull render (bidliet fl-identità tal-oġġett ta' mutazzjoni)
lura (
<>
Ara l-Pen SurveyJS-03-SurveyJS [forked] minn sixthextinction.
onComplete jispara meta l-utent jilħaq it-tmiem tal-aħħar paġna viżibbli. Mela jekk it-total qatt ma jaqsam 100 u l-paġna tar-reviżjoni tinqabeż, xorta tispara b'mod korrett minħabba li SurveyJS jevalwa l-viżibilità qabel ma jiddeċiedi xi tfisser "l-aħħar paġna". Imbagħad, sender.data fih it-tweġibiet kollha flimkien mal-valuri kkalkulati (subtotal, taxxa, totali) bħala oqsma tal-ewwel klassi, għalhekk it-tagħbija tal-API hija identika għal dak li l-verżjoni RHF immuntat manwalment f'onSubmit. Il-Il-mudell mutationRef huwa l-istess wieħed li int tilħaq kullimkien għandek bżonn handler tal-avvenimenti stabbli fuq valur li jinbidel fuq kull render - xejn speċifiku għal SurveyJS dwaru.
Il-komponent React m'għadux fih ebda loġika tan-negozju. M'hemm l-ebda useWatch, l-ebda JSX kondizzjonali, l-ebda pass counter, l-ebda katina useMemo, l-ebda superRefine. React qed tagħmel dak li fil-fatt hu tajjeb: tirrendi komponent u twaħħalha għal sejħa API. X'Imċaqlaq Mill-React?
Tħassib Munzell RHF StħarriġJS Viżibilità fergħat JSX viżibbliJekk Valuri derivati użaWatch / użaMemo espressjoni Regoli cross-field superRefine Kundizzjonijiet tal-iskema Navigazzjoni stat pass Paġna viżibbliJekk Regola post Imqassam fuq fajls Ċentralizzat fl-iskema
Dak li jibqa 'f'React huwa t-tqassim, l-istil, il-wajers tas-sottomissjoni, u l-integrazzjoni tal-app, jiġifieri, l-affarijiet li React huwa attwalment iddisinjat għalihom. Kollox ieħor imċaqlaq fl-iskema, u minħabba li l-iskema hija biss oġġett JSON, tista 'tinħażen f'database, verżjoni verżjoni indipendenti mill-kodiċi tal-applikazzjoni tiegħek, jew editjata permezz ta' għodda interna mingħajr ma teħtieġ skjerament. Maniġer tal-prodott li jeħtieġ li jibdel il-limitu li jqajjem il-paġna ta 'reviżjoni jista' jagħmel dan mingħajr ma jmiss il-komponent. Dik hija differenza operattiva sinifikanti għal timijiet fejn l-imġieba tal-forma tevolvi ta 'spiss u mhux dejjem tkun immexxija minn inġiniera. Meta Uża Kull Approċċ? Hawnhekk hawn regola tajba li taħdem għalija: immaġina li tħassar il-formola għal kollox. X'titlef?
Jekk huma skrins, trid forom immexxija mill-komponenti. Jekk hija loġika tan-negozju, bħal limiti, regoli tal-fergħat, u rekwiżiti kondizzjonali li jikkodifikaw deċiżjonijiet reali, trid magna schema.
Bl-istess mod, jekk il-bidliet li ġejjin huma l-aktar dwar tikketti, oqsma, u t-tqassim, RHF se sservik tajjeb. Jekk huma dwar kundizzjonijiet, riżultati, u regoli li l-ops jew it-tim legali tiegħek jista 'jkollhom bżonn jaġġustaw nhar it-Tlieta wara nofsinhar mingħajr ma tippreżenta biljett, il-mudell ta' skema ma' SurveyJS huwa l-aktar adattat. Dawn iż-żewġ approċċi mhumiex verament f'kompetizzjoni ma' xulxin. Jindirizzaw klassijiet differenti ta' problemi, u l-iżball li ta' min jiġi evitat huwa li l-astrazzjoni ma titqabbadx mal-piż tal-loġika — tittratta sistema ta' regola bħal komponent għax dik hija l-għodda familjari, jew tilħaq magna tal-politika minħabba li formola kibret għal tliet passi u kisbet qasam kondizzjonali. Il-forma li bnejna hawn tpoġġi ħdejn il-konfini deliberatament, kumplessa biżżejjed biex tesponi d-differenza iżda mhux daqshekk estrema li t-tqabbil iħossu armat. Il-biċċa l-kbira tal-forom reali li saru diffiċli fil-codebase tiegħek probabbilment joqogħdu ħdejn dak l-istess limitu, u l-mistoqsija hija ġeneralment biss jekk xi ħadd issemmiex dak li fil-fatt huma. Uża React Hook Form + Zod meta:
Il-formoli huma orjentati lejn CRUD; Il-loġika hija baxxa u mmexxija mill-UI; L-inġiniera għandhom l-imġieba kollha; Backend jibqa’ s-sors tal-verità.
Uża SurveyJS meta:
Formoli jikkodifikaw deċiżjonijiet kummerċjali; Ir-regoli jevolvu indipendentement mill-UI; Il-loġika trid tkun viżibbli, verifikabbli, jew verżjoni; Mhux inġiniera jinfluwenzaw l-imġiba; L-istess forma trid taħdem fuq frontends multipli.