Αυτό το άρθρο χρηματοδοτείται από την SurveyJS Υπάρχει ένα νοητικό μοντέλο που μοιράζονται οι περισσότεροι προγραμματιστές του React χωρίς να το συζητούν ποτέ δυνατά. Ότι οι φόρμες υποτίθεται ότι είναι πάντα συστατικά. Αυτό σημαίνει μια στοίβα όπως:
React Hook Form για τοπική κατάσταση (ελάχιστες αναπαραγωγές, εργονομική καταχώρηση πεδίου, επιτακτική αλληλεπίδραση). Zod για επικύρωση (ορθότητα εισαγωγής, επικύρωση ορίων, ανάλυση ασφαλούς τύπου). React Query για backend: υποβολή, επαναλήψεις, προσωρινή αποθήκευση, συγχρονισμός διακομιστή και ούτω καθεξής.
Και για τη συντριπτική πλειονότητα των φορμών — τις οθόνες σύνδεσής σας, τις σελίδες ρυθμίσεών σας, τα μοντέλα CRUD σας — αυτό λειτουργεί πολύ καλά. Κάθε κομμάτι κάνει τη δουλειά του, συνθέτουν καθαρά και μπορείτε να προχωρήσετε στα μέρη της εφαρμογής σας που πραγματικά διαφοροποιούν το προϊόν σας. Αλλά κάθε τόσο, μια φόρμα αρχίζει να συγκεντρώνει πράγματα όπως κανόνες ορατότητας που εξαρτώνται από προηγούμενες απαντήσεις ή παράγωγες τιμές που διαιρούνται σε τρία πεδία. Ίσως ακόμη και ολόκληρες σελίδες που θα πρέπει να παραβλεφθούν ή να εμφανιστούν με βάση το τρέχον σύνολο. Μπορείτε να χειριστείτε την πρώτη υπό όρους με ένα useWatch και έναν ενσωματωμένο κλάδο, κάτι που είναι εντάξει. Μετά άλλο. Στη συνέχεια, προσεγγίζετε το superRefine για να κωδικοποιήσετε κανόνες μεταξύ πεδίων που το σχήμα Zod σας δεν μπορεί να εκφράσει με τον κανονικό τρόπο. Στη συνέχεια, η πλοήγηση στα βήματα αρχίζει να διαρρέει επιχειρηματική λογική. Κάποια στιγμή, κοιτάτε τι έχετε δημιουργήσει και συνειδητοποιείτε ότι η φόρμα δεν είναι πια πραγματικά διεπαφή χρήστη. Είναι περισσότερο μια διαδικασία απόφασης και το δέντρο συστατικών είναι ακριβώς εκεί που έτυχε να το αποθηκεύσετε. Εδώ νομίζω ότι καταρρέει το νοητικό μοντέλο για τις φόρμες στο React και πραγματικά κανείς δεν φταίει. Η στοίβα RHF + Zod είναι εξαιρετική σε αυτό για το οποίο σχεδιάστηκε. Το θέμα είναι ότι τείνουμε να συνεχίσουμε να το χρησιμοποιούμε πέρα από το σημείο όπου οι αφαιρέσεις του ταιριάζουν με το πρόβλημα, επειδή η εναλλακτική απαιτεί εντελώς διαφορετικό τρόπο σκέψης για τις μορφές. Αυτό το άρθρο αφορά αυτήν την εναλλακτική. Για να το δείξουμε αυτό, θα δημιουργήσουμε την ίδια ακριβώς φόρμα πολλαπλών βημάτων δύο φορές:
Με το React Hook Form + Zod συνδεδεμένο στο React Query για υποβολή, Με το SurveyJS, το οποίο αντιμετωπίζει μια φόρμα ως δεδομένα - ένα απλό σχήμα JSON - αντί ως δέντρο συνιστωσών.
Ίδιες απαιτήσεις, ίδια λογική υπό όρους, ίδια κλήση API στο τέλος. Στη συνέχεια, θα χαρτογραφήσουμε ακριβώς τι μετακινήθηκε και τι παρέμεινε και θα παρουσιάσουμε έναν πρακτικό τρόπο για να αποφασίσετε ποιο μοντέλο θα χρησιμοποιήσετε και πότε. Η φόρμα που φτιάχνουμε:
Αυτή η φόρμα θα χρησιμοποιεί μια ροή 4 βημάτων: Βήμα 1: Λεπτομέρειες
Όνομα (απαιτείται), Email (απαιτείται, έγκυρη μορφή).
Βήμα 2: Παραγγελία
Τιμή μονάδας, Ποσότητα, φορολογικός συντελεστής, Προκύπτουν: Μερικό σύνολο, Φόρος, Σύνολο.
Βήμα 3: Λογαριασμός και σχόλια
Έχετε λογαριασμό; (Ναι/Όχι) Εάν Ναι → όνομα χρήστη + κωδικός πρόσβασης, απαιτούνται και τα δύο. Εάν Όχι, → email έχει ήδη συλλεχθεί στο βήμα 1.
Βαθμολογία ικανοποίησης (1–5) Αν ≥ 4 → ρωτήσετε "Τι σας άρεσε;" Εάν ≤ 2 → ρωτήσετε "Τι μπορούμε να βελτιώσουμε;"
Βήμα 4: Επανεξέταση
Εμφανίζεται μόνο εάν σύνολο >= 100 Τελική υποβολή.
Αυτό δεν είναι ακραίο. Αλλά είναι αρκετό για να αποκαλύψει τις αρχιτεκτονικές διαφορές. Μέρος 1: Βασισμένο σε στοιχεία (React Hook Form + Zod) Εγκατάσταση npm εγκατάσταση react-hook-form zod @hookform/resolvers @tanstack/react-query
Σχήμα Zod Ας ξεκινήσουμε με το σχήμα Zod, γιατί συνήθως εκεί εδραιώνεται το σχήμα της φόρμας. Για τα δύο πρώτα βήματα — προσωπικά στοιχεία και εισαγωγές παραγγελιών — όλα είναι απλά: απαιτούμενες συμβολοσειρές, αριθμοί με ελάχιστα και ένα πλήθος. Το ενδιαφέρον μέρος ξεκινά όταν προσπαθείτε να εκφράσετε τους υπό όρους κανόνες.
εισαγωγή { z } από "zod";
εξαγωγή const formSchema = z.object({ firstName: z.string().min(1, "Απαιτείται"), email: z.string().email("Invalid email"), τιμή: z.number().min(0), quantity: z.number().min(1), taxRate: z.number(), has Account:[name:"]enum. z.string().optional(), κωδικός πρόσβασης: z.string().optional(), ικανοποίηση: z.number().min(1).max(5), positiveFeedback: z.string().optional(), improvementFeedback: z.string().optional(),}).superRefine((data, {Afsda) = "Ifsda)=ha"=>> (!data.username) { ctx.addIssue({ code: "custom", path: ["username"], message: "Required" } } if (!data.password || data.password.length < 6) { ctx.addIssue({ code: "custom", path:"}); }
if (data.satisfaction >= 4 && !data.positiveFeedback) { ctx.addIssue({ code: "custom", path: ["positiveFeedback"], message: "Please share that you like" }); }
if (data.satisfaction <= 2 && !data.improvementFeedback) { ctx.addIssue({ code: "custom", path:["improvementFeedback"], μήνυμα: "Πες μας τι να βελτιώσουμε" }); }});
τύπος εξαγωγής FormData = z.infer
Σημειώστε ότι το όνομα χρήστη και ο κωδικός πρόσβασης πληκτρολογούνται ως optional() παρόλο που απαιτούνται υπό όρους, επειδή το σχήμα επιπέδου τύπου του Zod περιγράφει το σχήμα του αντικειμένου και όχι τους κανόνες που διέπουν πότε τα πεδία έχουν σημασία. Η υπό όρους απαίτηση πρέπει να βρίσκεται μέσα στο superRefine, το οποίο εκτελείται μετά την επικύρωση του σχήματος και έχει πρόσβαση στο πλήρες αντικείμενο. Αυτός ο διαχωρισμός δεν είναι ελάττωμα. είναι ακριβώς αυτό για το οποίο έχει σχεδιαστεί το εργαλείο: το superRefine είναι το σημείο όπου η λογική μεταξύ πεδίων πηγαίνει όταν δεν μπορεί να εκφραστεί στην ίδια τη δομή του σχήματος. Αυτό που είναι επίσης αξιοσημείωτο εδώ είναι τι δεν εκφράζει αυτό το σχήμα. Δεν έχει έννοια σελίδων, δεν έχει ιδέα για το ποια πεδία είναι ορατά σε ποιο σημείο και δεν έχει έννοια πλοήγησης. Όλα αυτά θα ζήσουν κάπου αλλού. Στοιχείο φόρμας
εισαγωγή { useForm, useWatch } από "react-hook-form";εισαγωγή { zodResolver } από "@hookform/resolvers/zod";εισαγωγή { useMutation } από "@tanstack/react-query";εισαγωγή {useState, useMemo } από "react", εισαγωγή τύπος {formSche,
const STEPS = ["λεπτομέρειες", "παραγγελία", "λογαριασμός", "αναθεώρηση"];
πληκτρολογήστε OrderPayload = FormData & { subtotal: number; φόρος: αριθμός; σύνολο: αριθμός };
συνάρτηση εξαγωγής RHFMultiStepForm() { const [βήμα, setStep] = useState(0);
const mutation = useMutation({ mutationFn: async (ωφέλιμο φορτίο: OrderPayload) => { const res = await fetch("/api/orders", { μέθοδος: "POST", κεφαλίδες: { "Content-Type": "application/json" }, σώμα: JSON.stringify(ωφέλιμο φορτίο), }); εάν (!res.ok) ρίχνει νέο Σφάλμα("Αποτυχία υποβολής"); return res.json(); }, });
const { register, control, handleSubmit, formState: { errors }, } = useForm
επιστροφή (
);}Δείτε το Pen SurveyJS-03-RHF [διχαλωτή] από το sixthextinction. Συμβαίνουν πολλά εδώ και αξίζει να επιβραδύνετε για να παρατηρήσετε πού κατέληξαν τα πράγματα.
Οι παραγόμενες τιμές — υποσύνολο, φόρος, σύνολο — υπολογίζονται στο στοιχείο μέσω του useWatch και του useMemo, επειδή εξαρτώνται από τις τιμές ζωντανών πεδίων και δεν υπάρχει άλλο φυσικό μέρος για αυτές. Οι κανόνες ορατότητας για το όνομα χρήστη, τον κωδικό πρόσβασης, τη θετική ανατροφοδότηση και τη βελτίωση των ανατροφοδοτήσεων ζωντανά στο JSX ως ενσωματωμένες προϋποθέσεις. Η λογική παράβλεψης βημάτων — η σελίδα αξιολόγησης εμφανίζεται μόνο όταν το σύνολο >= 100 — είναι ενσωματωμένη στη μεταβλητή showSubmit και στη συνθήκη απόδοσης στο βήμα 3. Η ίδια η πλοήγηση είναι απλώς ένας μετρητής useState που αυξάνουμε με μη αυτόματο τρόπο. Το React Query χειρίζεται τις επαναλήψεις, την προσωρινή αποθήκευση και την ακύρωση. Η φόρμα απλώς καλεί mutation.mutate με επικυρωμένα δεδομένα.
Τίποτα από αυτά δεν είναι λάθος, από μόνο του. Αυτό εξακολουθεί να είναι ιδιωματικό React και το στοιχείο είναι αρκετά αποδοτικό χάρη στον τρόπο με τον οποίο οι απομονώσεις RHF αποδίδονται εκ νέου. Αλλά αν το παραδώσετε αυτό σε κάποιον που δεν το είχε γράψει και του ζητούσατε να εξηγήσει υπό ποιες συνθήκες εμφανίζεται η σελίδα κριτικής, θα έπρεπε να ανιχνεύσει μέσω του showSubmit, της συνθήκης απόδοσης του βήματος 3 και της λογικής του κουμπιού πλοήγησης - τρία ξεχωριστά σημεία - για να ανακατασκευάσει έναν κανόνα που θα μπορούσε να είχε δηλωθεί σε μια γραμμή. Η φόρμα λειτουργεί, ναι, αλλά η συμπεριφορά δεν είναι πραγματικά επιθεωρήσιμη ως σύστημα. Πρέπει να εκτελεστεί διανοητικά. Το πιο σημαντικό, η αλλαγή του απαιτεί εμπλοκή μηχανικού. Ακόμη και μια μικρή προσαρμογή, όπως η προσαρμογή όταν εμφανίζεται το βήμα ελέγχου, σημαίνει επεξεργασία του στοιχείου, ενημέρωση επικύρωσης, άνοιγμα ενός αιτήματος έλξης, αναμονή για έλεγχο και ανάπτυξη ξανά. Μέρος 2: Καθοδηγούμενο από σχήμα (SurveyJS) Τώρα ας δημιουργήσουμε την ίδια ροή χρησιμοποιώντας ένα σχήμα. Εγκατάσταση npm εγκατάσταση survey-core survey-react-ui @tanstack/react-query
survey-core Ο μηχανισμός χρόνου εκτέλεσης, ανεξάρτητος από πλατφόρμα, με άδεια MIT που τροφοδοτεί την απόδοση φόρμας του SurveyJS — το μέρος που μας ενδιαφέρει εδώ. Παίρνει ένα σχήμα JSON, δημιουργεί ένα εσωτερικό μοντέλο από αυτό και χειρίζεται όλα όσα θα βρίσκονταν διαφορετικά στο στοιχείο React σας: αξιολόγηση παραστάσεων ορατότητας, υπολογισμός παραγόμενων τιμών, διαχείριση κατάστασης σελίδας, παρακολούθηση επικύρωσης και απόφαση για το τι σημαίνει "πλήρη" δεδομένου ποιες σελίδες εμφανίζονταν στην πραγματικότητα.
survey-react-uiΤο επίπεδο διεπαφής χρήστη / απόδοσης που συνδέει αυτό το μοντέλο με το React. Είναι ουσιαστικά ένα στοιχείο
Μαζί, σας προσφέρουν έναν πλήρως λειτουργικό χρόνο εκτέλεσης φόρμας πολλών σελίδων χωρίς να γράφετε ούτε μια γραμμή ροής ελέγχου. Η ίδια η μορφή σχήματος είναι, όπως αναφέρθηκε προηγουμένως, απλώς JSON — χωρίς DSL ή οτιδήποτε ιδιόκτητο. Μπορείτε να το ενσωματώσετε, να το εισαγάγετε από ένα αρχείο, να το ανακτήσετε από ένα API ή να το αποθηκεύσετε σε μια στήλη βάσης δεδομένων και να το ενυδατώσετε κατά το χρόνο εκτέλεσης. Η ίδια μορφή, με τα δεδομένα Εδώ είναι η ίδια μορφή, αυτή τη φορά που εκφράζεται ως αντικείμενο JSON. Το σχήμα ορίζει τα πάντα: δομή, επικύρωση, κανόνες ορατότητας, παραγόμενους υπολογισμούς, πλοήγηση σελίδας — και το παραδίδει σε ένα μοντέλο που το αξιολογεί κατά το χρόνο εκτέλεσης. Δείτε πώς φαίνεται πλήρως:
εξαγωγή const surveySchema = { title: "Order Flow", showProgressBar: "top", pages: [ { name: "details", στοιχεία: [ { type: "text", name: "firstName", isRequired: true }, { type: "text", name: "email", inputType: "email", isRequired: "email", isRequired: "email", validators: }] } ] }, { όνομα: "παραγγελία", στοιχεία: [ { type: "text", name: "price", inputType: "number", defaultValue: 0 }, { type: "text", name: "quantity", inputType: "number", default Value: 1 }, { type: "dropdown",όνομα: "taxRate", defaultValue: 0,1, επιλογές: [ { value: 0,05, text: "5%" }, { value: 0.1, text: "10%" }, { value: 0.15, text: "15%" } ] }, { type: "expression", name: "Subtotal" "expression", όνομα: "φόρος", έκφραση: "{subtotal} {taxRate}" }, { type: "expression", name: "total", έκφραση: "{subtotal} + {tax}" } ] }, { name: "account", στοιχεία: [ { type: "radiogroup", name: "hasAccount""No [hasAccount]"Type:Y,} επιλογή: "username", visualIf: "{hasAccount} = 'Yes'", isRequired: true }, { type: "text", name: "password", inputType: "password", visualIf: "{hasAccount} = 'Yes'", isRequired: true, validators: [{ type: "text", mins] "Leng:" type: "rating", όνομα: "satisfaction", rateMin: 1, rateMax: 5 }, { type: "comment", name: "positiveFeedback", visualIf: "{satisfaction} >= 4" }, { type: "comment", name: "improvementFeedback", visualIf: "{satisfaction""} visualIf: "{total} >= 100", στοιχεία: [] } ]};
Συγκρίνετε αυτό για λίγο με την έκδοση RHF.
Το μπλοκ superRefine που απαιτούσε υπό όρους όνομα χρήστη και κωδικό πρόσβασης έχει φύγει. visualIf: "{hasAccount} = 'Yes'" σε συνδυασμό με το isRequired: true χειρίζεται και τις δύο ανησυχίες μαζί, στο ίδιο το πεδίο, όπου θα περιμένατε να τις βρείτε. Η αλυσίδα useWatch + useMemo που υπολόγισε το υποσύνολο, τον φόρο και το σύνολο αντικαθίσταται από τρία πεδία έκφρασης που αναφέρονται το ένα στο άλλο με όνομα. Η συνθήκη σελίδας αναθεώρησης, η οποία στην έκδοση RHF ήταν ανακατασκευή μόνο μέσω του showSubmit, του κλάδου απόδοσης του βήματος 3. Και τέλος, η λογική του κουμπιού πλοήγησης είναι μια ενιαία ιδιότητα visualIf στο αντικείμενο της σελίδας.
Η ίδια λογική υπάρχει. Απλώς το σχήμα του δίνει ένα μέρος για να ζήσει όπου είναι ορατό μεμονωμένα, αντί να απλώνεται σε όλο το στοιχείο. Επίσης, σημειώστε ότι το σχήμα χρησιμοποιεί τον τύπο: "έκφραση" για υποσύνολο, φόρο και σύνολο. Η έκφραση είναι μόνο για ανάγνωση και χρησιμοποιείται κυρίως για την εμφάνιση υπολογισμένων τιμών. Το SurveyJS υποστηρίζει επίσης τύπο: 'html' για στατικό περιεχόμενο, αλλά για υπολογισμένες τιμές, η έκφραση είναι η σωστή επιλογή. Τώρα για την πλευρά του React. Απόδοση και υποβολή Πολύ απλό. Συνδέστε onComplete στο API σας με τον ίδιο τρόπο — μέσω useMutation ή απλής ανάκτησης:
εισαγωγή { useState, useEffect, useRef } από "react", εισαγωγή { useMutation } από "@tanstack/react-query"; εισαγωγή { Model } από "survey-core"; εισαγωγή { Survey } από "survey-react-ui", εισαγωγή "survey-core/curvey-core".
συνάρτηση εξαγωγής SurveyForm() { const [model] = useState(() => new Model(surveySchema));
const mutation = useMutation({ mutationFn: async (data) => { const res = await fetch("/api/orders", { μέθοδος: "POST", κεφαλίδες: { "Content-Type": "application/json" }, σώμα: JSON.stringify(data), }); εάν (!res.ok) ρίχνει νέο Σφάλμα("Αποτυχία υποβολής"); return res.json(); }, });
const mutationRef = useRef(mutation); mutationRef.current = μετάλλαξη; useEffect(() => {const handler = (sender) => mutationRef.current.mutate(sender.data); model.onComplete.add(handler); return () => model.onComplete.remove(handler); }, [model]); // ref αποφεύγει την επανεγγραφή του χειριστή κάθε απόδοσης (αλλάζει η ταυτότητα αντικειμένου μετάλλαξης)
επιστροφή (
<>
Δείτε το Pen SurveyJS-03-SurveyJS [forked] by sixthextinction.
Το onComplete ενεργοποιείται όταν ο χρήστης φτάσει στο τέλος της τελευταίας ορατής σελίδας. Επομένως, εάν το σύνολο δεν ξεπεράσει ποτέ το 100 και η σελίδα αξιολόγησης παραλειφθεί, εξακολουθεί να ενεργοποιείται σωστά επειδή το SurveyJS αξιολογεί την ορατότητα πριν αποφασίσει τι σημαίνει "τελευταία σελίδα". Στη συνέχεια, το sender.data περιέχει όλες τις απαντήσεις μαζί με τις υπολογιζόμενες τιμές (υποσύνολο, φόρος, σύνολο) ως πεδία πρώτης κατηγορίας, επομένως το ωφέλιμο φορτίο API είναι πανομοιότυπο με αυτό που συναρμολόγησε η έκδοση RHF με μη αυτόματο τρόπο στο onSubmit. ΟΤο μοτίβο mutationRef είναι το ίδιο που θα προσεγγίζατε οπουδήποτε χρειάζεστε ένα σταθερό πρόγραμμα χειρισμού συμβάντων σε μια τιμή που αλλάζει σε κάθε απόδοση — τίποτα συγκεκριμένο για το SurveyJS.
Το στοιχείο React δεν περιέχει πλέον καμία επιχειρηματική λογική. Δεν υπάρχει useWatch, JSX υπό όρους, μετρητής βημάτων, αλυσίδα useMemo, superRefine. Το React κάνει αυτό στο οποίο είναι πραγματικά καλό: απόδοση ενός στοιχείου και καλωδίωση σε μια κλήση API. Τι Moved Out Of React;
Ανησυχία Στοίβα RHF SurveyJS Ορατότητα Υποκαταστήματα JSX ορατό Αν Παράγωγες τιμές useWatch / useMemo έκφραση Κανόνες μεταξύ πεδίων Υπερβελτίωση Συνθήκες σχήματος Πλοήγηση βήμα κατάσταση Σελίδα ορατήΑν Τοποθεσία κανόνα Κατανεμημένο σε αρχεία Συγκεντρωμένο στο σχήμα
Αυτό που παραμένει στο React είναι η διάταξη, το στυλ, η καλωδίωση υποβολής και η ενσωμάτωση εφαρμογών, δηλαδή τα πράγματα για τα οποία έχει σχεδιαστεί το React. Όλα τα άλλα μετακινήθηκαν στο σχήμα και επειδή το σχήμα είναι απλώς ένα αντικείμενο JSON, μπορεί να αποθηκευτεί σε μια βάση δεδομένων, να εκδοθεί ανεξάρτητα από τον κώδικα της εφαρμογής σας ή να επεξεργαστεί μέσω εσωτερικών εργαλείων χωρίς να απαιτείται ανάπτυξη. Ένας διαχειριστής προϊόντων που πρέπει να αλλάξει το όριο που ενεργοποιεί τη σελίδα αξιολόγησης μπορεί να το κάνει χωρίς να αγγίξει το στοιχείο. Αυτή είναι μια σημαντική λειτουργική διαφορά για ομάδες όπου η συμπεριφορά της μορφής εξελίσσεται συχνά και δεν καθοδηγείται πάντα από μηχανικούς. Πότε να χρησιμοποιήσετε κάθε προσέγγιση; Εδώ είναι ένας καλός εμπειρικός κανόνας που λειτουργεί για μένα: φανταστείτε να διαγράψετε εντελώς τη φόρμα. Τι θα έχανες;
Εάν είναι οθόνες, θέλετε φόρμες που βασίζονται σε στοιχεία. Εάν είναι επιχειρηματική λογική, όπως κατώφλια, κανόνες διακλάδωσης και απαιτήσεις υπό όρους που κωδικοποιούν πραγματικές αποφάσεις, θέλετε μια μηχανή σχήματος.
Ομοίως, εάν οι αλλαγές που έρχονται στο δρόμο σας αφορούν κυρίως ετικέτες, πεδία και διάταξη, το RHF θα σας εξυπηρετήσει μια χαρά. Αν πρόκειται για συνθήκες, αποτελέσματα και κανόνες που μπορεί να χρειαστεί να προσαρμόσουν οι επιχειρηματίες ή η νομική σας ομάδα το απόγευμα της Τρίτης χωρίς να υποβάλετε εισιτήριο, το μοντέλο σχήματος με το SurveyJS ταιριάζει καλύτερα. Αυτές οι δύο προσεγγίσεις δεν ανταγωνίζονται πραγματικά η μία την άλλη. Αντιμετωπίζουν διαφορετικές κατηγορίες προβλημάτων και το λάθος που αξίζει να αποφευχθεί είναι η αναντιστοιχία της αφαίρεσης με το βάρος της λογικής — αντιμετωπίζοντας ένα σύστημα κανόνων σαν στοιχείο επειδή αυτό είναι το γνωστό εργαλείο ή αναζητώντας μια μηχανή πολιτικής επειδή μια φόρμα αυξήθηκε σε τρία βήματα και απέκτησε ένα πεδίο υπό όρους. Η φόρμα που κατασκευάσαμε εδώ βρίσκεται κοντά στο όριο σκόπιμα, αρκετά περίπλοκη για να εκθέσει τη διαφορά αλλά όχι τόσο ακραία ώστε η σύγκριση να φαίνεται στημένη. Οι περισσότερες πραγματικές φόρμες που έχουν γίνει δύσχρηστες στη βάση κωδίκων σας πιθανότατα βρίσκονται κοντά στο ίδιο όριο και το ερώτημα είναι συνήθως μόνο αν κάποιος έχει ονομάσει τι είναι στην πραγματικότητα. Χρησιμοποιήστε το React Hook Form + Zod όταν:
Οι φόρμες είναι προσανατολισμένες στο CRUD. Η λογική είναι ρηχή και βασίζεται στο UI. Οι μηχανικοί κατέχουν κάθε συμπεριφορά. Το Backend παραμένει η πηγή της αλήθειας.
Χρησιμοποιήστε το SurveyJS όταν:
Τα έντυπα κωδικοποιούν επιχειρηματικές αποφάσεις. Οι κανόνες εξελίσσονται ανεξάρτητα από τη διεπαφή χρήστη. Η λογική πρέπει να είναι ορατή, ελεγχόμενη ή τροποποιημένη. Οι μη μηχανικοί επηρεάζουν τη συμπεριφορά. Η ίδια φόρμα πρέπει να εκτελείται σε πολλές διεπαφές.