இந்தக் கட்டுரை SurveyJS ஆல் ஸ்பான்சர் செய்யப்பட்டது பெரும்பாலான ரியாக்ட் டெவலப்பர்கள் சத்தமாக விவாதிக்காமல் பகிர்ந்து கொள்ளும் மன மாதிரி உள்ளது. அந்த வடிவங்கள் எப்போதும் கூறுகளாக இருக்க வேண்டும். இது போன்ற ஒரு அடுக்கைக் குறிக்கிறது:

உள்ளூர் மாநிலத்திற்கான ரியாக்ட் ஹூக் படிவம் (குறைந்தபட்ச மறு-ரெண்டர்கள், பணிச்சூழலியல் புல பதிவு, கட்டாய தொடர்பு). சரிபார்ப்புக்கான Zod (உள்ளீடு சரியானது, எல்லை சரிபார்ப்பு, வகை-பாதுகாப்பான பாகுபடுத்தல்). பின்தளத்திற்கான ரியாக்ட் வினவல்: சமர்ப்பித்தல், மறுமுயற்சிகள், கேச்சிங், சர்வர் ஒத்திசைவு மற்றும் பல.

மற்றும் பெரும்பாலான படிவங்களுக்கு - உங்கள் உள்நுழைவுத் திரைகள், உங்கள் அமைப்புகள் பக்கங்கள், உங்கள் CRUD மாதிரிகள் - இது நன்றாக வேலை செய்கிறது. ஒவ்வொரு பகுதியும் அதன் வேலையைச் செய்கிறது, அவை சுத்தமாக உருவாக்கப்படுகின்றன, மேலும் உங்கள் தயாரிப்பை வேறுபடுத்தும் உங்கள் பயன்பாட்டின் பகுதிகளுக்கு நீங்கள் செல்லலாம். ஆனால் ஒவ்வொரு முறையும், ஒரு படிவம் முந்தைய பதில்களைச் சார்ந்து இருக்கும் தெரிவுநிலை விதிகள் அல்லது மூன்று புலங்களில் அடுக்கி வைக்கப்படும் பெறப்பட்ட மதிப்புகள் போன்ற விஷயங்களைக் குவிக்கத் தொடங்குகிறது. முழு பக்கங்களும் தவிர்க்கப்பட வேண்டும் அல்லது இயங்கும் மொத்தத்தின் அடிப்படையில் காட்டப்பட வேண்டும். யூஸ்வாட்ச் மற்றும் இன்லைன் கிளை மூலம் முதல் நிபந்தனையை நீங்கள் கையாளுகிறீர்கள், இது நன்றாக இருக்கிறது. பிறகு மற்றொன்று. உங்கள் Zod ஸ்கீமாவால் இயல்பான முறையில் வெளிப்படுத்த முடியாத குறுக்கு-புல விதிகளை குறியாக்க சூப்பர் ரீஃபைனை அணுகுகிறீர்கள். பின்னர், படி வழிசெலுத்தல் வணிக தர்க்கத்தை கசியத் தொடங்குகிறது. ஒரு கட்டத்தில், நீங்கள் உருவாக்கியதைப் பார்த்து, படிவம் உண்மையில் UI அல்ல என்பதை உணருங்கள். இது ஒரு முடிவெடுக்கும் செயல்முறையாகும், மேலும் கூறு மரமானது நீங்கள் அதைச் சேமித்து வைத்திருக்கும் இடமாகும். இங்குதான் ரியாக்டில் உள்ள வடிவங்களுக்கான மன மாதிரி உடைகிறது என்று நான் நினைக்கிறேன், அது உண்மையில் யாருடைய தவறும் இல்லை. RHF + Zod ஸ்டாக் எதற்காக வடிவமைக்கப்பட்டது என்பதில் சிறப்பாக உள்ளது. சிக்கல் என்னவென்றால், அதன் சுருக்கங்கள் சிக்கலுடன் பொருந்தக்கூடிய புள்ளியைக் கடந்தும் அதை நாங்கள் தொடர்ந்து பயன்படுத்த முனைகிறோம், ஏனெனில் மாற்றீட்டிற்கு வடிவங்களைப் பற்றி முற்றிலும் வேறுபட்ட சிந்தனை தேவைப்படுகிறது. இந்தக் கட்டுரை அந்த மாற்றைப் பற்றியது. இதைக் காட்ட, ஒரே மாதிரியான பல-படி படிவத்தை இரண்டு முறை உருவாக்குவோம்:

ரியாக்ட் ஹூக் படிவம் + சோட் மூலம் சமர்ப்பிப்பதற்காக வினவலுக்கு பதிலளிக்க, SurveyJS உடன், ஒரு படிவத்தை தரவுகளாகக் கருதுகிறது - ஒரு எளிய JSON ஸ்கீமா - ஒரு கூறு மரத்தை விட.

அதே தேவைகள், அதே நிபந்தனை தர்க்கம், முடிவில் அதே API அழைப்பு. அதன் பிறகு, என்ன நகர்த்தப்பட்டது, எது தங்கியது என்பதை நாங்கள் துல்லியமாக வரைபடமாக்குவோம், மேலும் நீங்கள் எந்த மாதிரியைப் பயன்படுத்த வேண்டும், எப்போது பயன்படுத்த வேண்டும் என்பதைத் தீர்மானிக்க ஒரு நடைமுறை வழியை அமைப்போம். நாங்கள் உருவாக்கும் படிவம்:

இந்தப் படிவம் 4-படி ஓட்டத்தைப் பயன்படுத்தும்: படி 1: விவரங்கள்

முதல் பெயர் (தேவை), மின்னஞ்சல் (தேவை, சரியான வடிவம்).

படி 2: ஆர்டர்

அலகு விலை, அளவு, வரி விகிதம், பெறப்பட்டது: கூட்டுத்தொகை, வரி, மொத்தம்.

படி 3: கணக்கு மற்றும் கருத்து

உங்களிடம் கணக்கு உள்ளதா? (ஆம்/இல்லை) ஆம் என்றால் → பயனர்பெயர் + கடவுச்சொல் இரண்டும் தேவை. இல்லை என்றால் → மின்னஞ்சல் ஏற்கனவே படி 1 இல் சேகரிக்கப்பட்டுள்ளது.

திருப்தி மதிப்பீடு (1–5) ≥ 4 → “உங்களுக்கு என்ன பிடித்தது?” என்று கேட்டால் ≤ 2 → கேட்டால் “நாம் எதை மேம்படுத்தலாம்?”

படி 4: மதிப்பாய்வு

மொத்தம் >= 100 இருந்தால் மட்டுமே தோன்றும் இறுதி சமர்ப்பிப்பு.

இது தீவிரமானது அல்ல. ஆனால் கட்டிடக்கலை வேறுபாடுகளை அம்பலப்படுத்த இது போதுமானது. பகுதி 1: கூறு-உந்துதல் (ரியாக்ட் ஹூக் படிவம் + ஜோட்) நிறுவல் npm react-hook-form zod @hookform/resolvers @tanstack/react-query நிறுவவும்

ஜோட் ஸ்கீமா Zod ஸ்கீமாவுடன் ஆரம்பிக்கலாம், ஏனென்றால் பொதுவாக அங்குதான் படிவத்தின் வடிவம் நிறுவப்படும். முதல் இரண்டு படிகளுக்கு - தனிப்பட்ட விவரங்கள் மற்றும் ஆர்டர் உள்ளீடுகள் - அனைத்தும் நேரடியானவை: தேவையான சரங்கள், குறைந்தபட்ச எண்கள் மற்றும் ஒரு எண். நீங்கள் நிபந்தனை விதிகளை வெளிப்படுத்த முயற்சிக்கும்போது சுவாரஸ்யமான பகுதி தொடங்குகிறது.

"zod" இலிருந்து {z } ஐ இறக்குமதி செய்;

export const formSchema = z.object({ firstName: z.string().min(1, "Required"), email: z.string().email("தவறான மின்னஞ்சல்"), விலை: z.number().min(0), அளவு: z.number().min(1), taxRate: z.ncumber: z.ncumber z.enum(["Yes", "No"]), பயனர்பெயர்: z.string().விரும்பினால்(), கடவுச்சொல்: z.string().விரும்பினால்(), திருப்தி: z.number().min(1).max(5), நேர்மறை கருத்து: z.string().supptional(), improvementalFeedback(). ctx) => {if (data.hasAccount === "Yes") {if (!data.username) {ctx.addIssue({குறியீடு: "தனிப்பயன்", பாதை: ["username"], செய்தி: "தேவை" }); {!data.password. "தனிப்பயன்", பாதை: ["கடவுச்சொல்"], செய்தி: "குறைந்தபட்சம் 6 எழுத்துகள்" });

என்றால் (data.satisfaction >= 4 && !data.positiveFeedback) {ctx.addIssue({குறியீடு: "தனிப்பயன்", பாதை: ["positiveFeedback"], செய்தி: "நீங்கள் விரும்பியதைப் பகிரவும்" }); }

என்றால் (data.satisfaction <= 2 && !data.improvementFeedback) { ctx.addIssue({ code: "custom", path:["மேம்படுத்தல் பின்னூட்டம்"], செய்தி: "எதை மேம்படுத்த வேண்டும் என்பதை எங்களிடம் கூறுங்கள்" }); }});

ஏற்றுமதி வகை FormData = z.infer;

Zod இன் வகை-நிலை ஸ்கீமா பொருளின் வடிவத்தை விவரிக்கிறது, புலங்கள் முக்கியமானதாக இருக்கும் போது நிர்வகிக்கும் விதிகள் அல்ல, ஏனெனில் பயனர்பெயர் மற்றும் கடவுச்சொல் ஆகியவை நிபந்தனையுடன் தேவைப்பட்டாலும் விருப்பத்தேர்வாக() தட்டச்சு செய்யப்படுகின்றன என்பதைக் கவனியுங்கள். நிபந்தனைத் தேவை சூப்பர் ரீஃபைனுக்குள் வாழ வேண்டும், இது வடிவம் சரிபார்க்கப்பட்ட பிறகு இயங்குகிறது மற்றும் முழு பொருளையும் அணுகும். அந்தப் பிரிதல் ஒரு குறை அல்ல; இந்தக் கருவி எதற்காக வடிவமைக்கப்பட்டுள்ளது: சூப்பர் ரீஃபைன் என்பது ஸ்கீமா கட்டமைப்பிலேயே வெளிப்படுத்த முடியாதபோது குறுக்கு-புலம் தர்க்கம் செல்லும். இங்கே குறிப்பிடத்தக்கது என்னவென்றால், இந்த திட்டம் வெளிப்படுத்தவில்லை. இதில் பக்கங்கள் பற்றிய கருத்து இல்லை, எந்த புள்ளியில் எந்த புலங்கள் தெரியும் என்ற கருத்து இல்லை, வழிசெலுத்தல் பற்றிய கருத்து இல்லை. அதெல்லாம் வேற எங்காவது வாழணும். படிவம் கூறு

"react-hook-form" இலிருந்து {useForm, useWatch}ஐ இறக்குமதி செய்க; "@hookform/resolvers/zod" இலிருந்து {zodResolver }ஐ இறக்குமதி செய்

const STEPS = ["விவரங்கள்", "ஆர்டர்", "கணக்கு", "மதிப்பாய்வு"];

வகை OrderPayload = FormData & { துணை மொத்தம்: எண்; வரி: எண்; மொத்தம்: எண்};

ஏற்றுமதி செயல்பாடு RHFMultiStepForm() {const [step, setStep] = useState(0);

மாறுதல் பிறழ்வு = உபயோகமாற்றம்({ mutationFn: async (பேலோடு: OrderPayload) => { const res = காத்திருங்கள் பெற ("/api/orders", { முறை: "POST", தலைப்புகள்: { "உள்ளடக்க வகை": "application/json" }, உடல்: JSON.stringify(payload), }); (!res.ok) புதிய பிழையை எறிந்தால் ("சமர்ப்பிப்பதில் தோல்வி"); திரும்ப res.json(); }, });

const {பதிவு, கட்டுப்பாடு, கையாளுதல், படிவநிலை: {பிழைகள்}, } = useForm({தீர்ப்பான்: zodResolver(formSchema), defaultValues: {விலை: 0, அளவு: 1, வரிவிகிதம்: 0.1, திருப்தி: 3, "Noc,count: }}}); const price = useWatch({கட்டுப்பாடு, பெயர்: "விலை"}); const quantity = useWatch({கட்டுப்பாடு, பெயர்: "அளவு"}); const taxRate = useWatch({கட்டுப்பாடு, பெயர்: "வரிவிகிதம்"}); const hasAccount = useWatch({ கட்டுப்பாடு, பெயர்: "hasAccount"}); const திருப்தி = useWatch({கட்டுப்பாடு, பெயர்: "திருப்தி"}); const subtotal = useMemo(() => (விலை ?? 0) * (அளவு ?? 1), [விலை, அளவு]); const tax = useMemo(() => subtotal * (taxRate ?? 0), [subtotal, taxRate]); const total = useMemo(() => subtotal + tax, [subtotal, tax]); const onSubmit = (தரவு: FormData) => mutation.mutate({ ...தரவு, துணைத்தொகை, வரி, மொத்தம்}); const showSubmit = (படி === 2 && மொத்தம் < 100) || (படி === 3 && மொத்தம் >= 100)

திரும்ப (

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

{step === 1 && ( <> <மதிப்பைத் தேர்ந்தெடு {...பதிவு எண் },> விருப்பத்தேர்வு value="0.05">5%

துணைத்தொகை: {subtotal}
வரி: {tax}
மொத்தம்: {total}
)}

{step === 2 && ( <> <தேர்ந்தெடு {...பதிவு("hasAccount")}>

{hasAccount === "ஆம்" && ( <> <உள்ளீடு {...register("username")} placeholder="Username" /> )}

{திருப்தி >= 4 && (