بۇ ماقالە SurveyJS نىڭ قوللىشىغا ئېرىشكەن كۆپىنچە رېئاكتىپ ئاچقۇچىلار ئۇنى يۇقىرى ئاۋازدا مۇنازىرە قىلماي ئورتاقلىشىدىغان روھىي مودېل بار. بۇ شەكىللەر ھەمىشە زاپچاس بولۇشى كېرەك. بۇ دېگەندەك بىر توپنى كۆرسىتىدۇ:

يەرلىك ھالەتتىكى قارماق جەدۋىلىنى قايتۇرۇڭ (ئەڭ تۆۋەن قايتا كۆرسىتىش ، ئېروگونومىيىلىك مەيداننى تىزىملاش ، مەجبۇرىي ئۆز-ئارا تەسىر كۆرسىتىش). دەلىللەشنىڭ نومۇرى (كىرگۈزۈش توغرىلىقى ، چېگرانى دەلىللەش ، تىپنى بىخەتەر تەھلىل قىلىش). ئارقا سۇپىدىكى سوئالغا جاۋاب بېرىش: يوللاش ، قايتا تەكشۈرۈش ، غەملەك ، مۇلازىمېتىر ماسقەدەملەش قاتارلىقلار.

مۇتلەق كۆپ قىسىم جەدۋەللەرگە - كىرىش ئېكرانىڭىز ، تەڭشەك بېتىڭىز ، CRUD مودېللىرىڭىز ئۈچۈن بۇ ھەقىقەتەن ياخشى ئىشلەيدۇ. ھەر بىر ئەسەر ئۆز خىزمىتىنى قىلىدۇ ، ئۇلار پاكىز يازىدۇ ، قوللىنىشچان پروگراممىڭىزنىڭ مەھسۇلاتىڭىزنى پەرقلەندۈرىدىغان قىسمىغا يۆتكىسىڭىز بولىدۇ. ئەمما ھەر قېتىمدا بىر جەدۋەل ئىلگىرىكى جاۋابلارغا باغلىق بولغان كۆرۈنۈشلۈك قائىدىلەر ياكى ئۈچ ساھەدە كاساتلاشقان قىممەت قارىشى قاتارلىق نەرسىلەرنى توپلاشقا باشلايدۇ. بەلكىم ئىجرا قىلىنىدىغان ئومۇمىي سانغا ئاساسەن ئاتلاپ كېتىش ياكى كۆرسىتىشكە تېگىشلىك بارلىق بەتلەر بولۇشى مۇمكىن. سىز تۇنجى شەرتنى useWatch ۋە ئىچكى شاخ بىلەن بىر تەرەپ قىلىسىز ، بۇ ياخشى. ئاندىن يەنە بىرى. ئاندىن سىز Zod لايىھىڭىز نورمال ئۇسۇلدا ئىپادىلىيەلمەيدىغان ساھە ھالقىغان قائىدىلەرنى كودلاش ئۈچۈن superRefine غا يېتىسىز. ئاندىن ، قەدەم باسقۇچلىرى سودا لوگىكىسىنى ئاشكارىلاشقا باشلايدۇ. بەزى ۋاقىتتا ، ئۆزىڭىزنىڭ نېمە قۇرغانلىقىڭىزغا قاراپ ، جەدۋەلنىڭ ئەمدى UI ئەمەسلىكىنى ھېس قىلىسىز. بۇ تېخىمۇ كۆپ قارار چىقىرىش جەريانى ، زاپچاس دەرىخى دەل ئۇنى ساقلىغان جاي. بۇ مېنىڭچە رېئاللىقتىكى شەكىللەرنىڭ روھىي ئەندىزىسى بۇزۇلدى ، بۇ ھەقىقەتەن ھېچكىمنىڭ خاتالىقى ئەمەس. RHF + Zod تىزىمى لايىھەلەنگەن. مەسىلە شۇكى ، بىز ئۇنىڭ ئابستراكتلىرى مەسىلىگە ماس كېلىدىغان نۇقتىدىن ئۆتۈپ كېتىشنى داۋاملاشتۇرىمىز ، چۈنكى تاللاش شەكلى پۈتۈنلەي باشقىچە تەپەككۇر ئۇسۇلىنى تەلەپ قىلىدۇ. بۇ ماقالە شۇ تاللاش ھەققىدە. بۇنى كۆرسىتىش ئۈچۈن ، بىز ئوخشاش ئىككى باسقۇچلۇق جەدۋەلنى ئىككى قېتىم قۇرىمىز:

React Hook Form + Zod ئارقىلىق سۇئالغا جاۋاب قايتۇرۇش ئۈچۈن ، SurveyJS بىلەن بىر جەدۋەلنى سانلىق مەلۇمات دەپ قارايدۇ - ئاددىي JSON پىلانى - زاپچاس دەرىخى ئەمەس.

ئوخشاش تەلەپ ، ئوخشاش شەرتلىك لوگىكا ، ئاخىرىدا ئوخشاش API چاقىرىش. ئاندىن بىز نېمىنىڭ يۆتكىلىپ ، نېمىنىڭ قالغانلىقىنى ئېنىق خەرىتىمىز ، ھەمدە قايسى مودېلنى ئىشلىتىش كېرەكلىكىنى ، قاچان قارار قىلىدىغان ئەمەلىي ئۇسۇلنى ئوتتۇرىغا قويىمىز. بىز قۇرغان جەدۋەل:

بۇ جەدۋەلدە 4 باسقۇچلۇق ئېقىم ئىشلىتىلىدۇ: 1-قەدەم: تەپسىلاتلار

ئىسمى (تەلەپ قىلىنغان) ، ئېلېكترونلۇق خەت (تەلەپ قىلىنغان ، ئۈنۈملۈك فورماتى).

ئىككىنچى قەدەم: زاكاز

بىرلىك باھاسى ، Quantity, باج نىسبىتى ، مەنبە: Subtotal, باج ، ئومۇمىي.

3-قەدەم: ھېسابات ۋە تەكلىپ

ھېساباتىڭىز بارمۇ؟ (ھەئە / ياق) ئەگەر ھەئە → ئىشلەتكۈچى ئىسمى + پارول بولسا ، ھەر ئىككىسى تەلەپ قىلىنىدۇ. ئەگەر No → ئېلېكترونلۇق خەت 1-قەدەمدە توپلانغان بولسا.

رازى بولۇش دەرىجىسى (1-5) ئەگەر ≥ 4 → «نېمىنى ياقتۇردىڭىز؟» دەپ سوراڭ. ئەگەر ≤ 2 → «بىز نېمىنى ياخشىلىيالايمىز؟» دەپ سورىسا.

4-قەدەم: تەكشۈرۈش

پەقەت ئومۇمىي = = 100 بولسا ئاندىن كۆرۈنىدۇ ئاخىرقى تاپشۇرۇش.

بۇ ھەددىدىن ئاشمايدۇ. ئەمما بىناكارلىق پەرقىنى ئاشكارىلاش يېتەرلىك. 1-قىسىم: زاپچاس قوزغاتقۇچ (قارماق شەكلى + Zod) قاچىلاش npm install react-hook-form zod @ hookform / resolvers @ tanstack / react-query

Zod Schema ئىشنى Zod پىلانىدىن باشلايلى ، چۈنكى بۇ ئادەتتە جەدۋەلنىڭ شەكلى تىكلىنىدىغان جاي. ئالدىنقى ئىككى باسقۇچ - شەخسىي تەپسىلاتلار ۋە زاكاز كىرگۈزۈش - ھەممە نەرسە بىۋاسىتە: تەلەپ قىلىنغان تىزمىلار ، ئەڭ تۆۋەن سان ۋە سانلار. قىزىقارلىق قىسمى شەرتلىك قائىدىلەرنى ئىپادىلىمەكچى بولغاندا باشلىنىدۇ.

"zod" دىن {z import

export const formSchema = z.object ({firstName: z.string (). min (1, "تەلەپ") ، ئېلخەت: z.string (). ئېلخەت ("ئىناۋەتسىز ئېلخەت") ، باھاسى: z.number (). min (0) ، سان z.string (). ئىختىيارىي () ، پارول: z.string (). ئىختىيارى () ، رازى بولۇش: z.number (). min (1) .max (5) (! data.username) {ctx.addIssue ({كود: "ئىختىيارى" ، يول:

if (data.satisfaction> = 4 &&! data.positiveFeedback) {ctx.addIssue ({كود: "ئىختىيارى" ، يول: }

if (data.satisfaction <= 2 &&! data.improvementFeedback) {ctx.addIssue ({code: "custom", path:["improvementFeedback"] ، ئۇچۇر: "نېمىنى ياخشىلاشنى بىزگە ئېيتىپ بېرىڭ"}); }});

چىقىرىش تىپى FormData = z.infer ;

شۇنىڭغا دىققەت قىلىڭكى ، ئىشلەتكۈچى ئىسمى ۋە پارولى شەرتلىك تەلەپ قىلىنغان تەقدىردىمۇ ئىختىيارى () دەپ يېزىلىدۇ ، چۈنكى Zod نىڭ تىپىدىكى لايىھە ئوبيېكتنىڭ شەكلىنى تەسۋىرلەيدۇ ، مەيدان مۇھىم بولغاندا قائىدە ئەمەس. شەرتلىك تەلەپ superRefine نىڭ ئىچىدە ياشىشى كېرەك ، بۇ شەكىل تەستىقلانغاندىن كېيىن ئىجرا بولىدۇ ھەمدە تولۇق جىسىمغا ئېرىشەلەيدۇ. بۇ ئايرىلىش نۇقسان ئەمەس. ئۇ پەقەت قورال ئۈچۈن لايىھەلەنگەن نەرسە: superRefine بولسا لايىھە قۇرۇلمىسىنىڭ ئۆزىدە ئىپادىلىگىلى بولمىغاندا ، مەيدان ھالقىغان لوگىكا بارىدىغان جاي. بۇ يەردە كىشىنىڭ دىققىتىنى تارتىدىغىنى بۇ پىلاننىڭ ئىپادىلەنمىگەن يېرى. ئۇنىڭدا بەت ئۇقۇمى ، قايسى ساھەدە قايسى نۇقتىدا كۆرۈنەلەيدىغانلىقى ۋە يول باشلاش ئۇقۇمى يوق. بۇلارنىڭ ھەممىسى باشقا جايدا ياشايدۇ. شەكىل زاپچاسلىرى

ئىمپورت {useForm, useWatch} "react-hook-form"; import @ zodResolver} "@ hookform / resolvers / zod" دىن ئىمپورت {import @ useMutation} "@ tanstack / react-query"; import {useState, useMemo} "reaction";

const STEPS = ["تەپسىلاتلار" ، "زاكاز" ، "ھېسابات" ، "تەكشۈرۈش"];

type OrderPayload = FormData & {subtotal: number; باج: سان ئومۇمىي: سان};

چىقىرىش ئىقتىدارى RHFMultiStepForm () {const [step, setStep] = useState (0);

const mutation = useMutation ({ mutationFn: async (payload: OrderPayload) => { const res = ساقلاشنى ساقلاش ("/ api / زاكاز", { ئۇسۇلى: "POST", ماۋزۇلار: {"مەزمۇن تىپى": "application / json"}, body: JSON.stringify (payload), }); if (! res.ok) يېڭى خاتالىق تاشلىسا ("تاپشۇرۇش مەغلۇب بولدى"); return res.json (); }, });

const {تىزىملاش ، كونترول قىلىش ، بىر تەرەپ قىلىش يوللاش ، جەدۋەل ھالىتى: {خاتالىق} ،} = useForm ({ھەل قىلغۇچ: zodResolver (formSchema) ، سۈكۈتتىكى قىممەت: const price = useWatch ({كونترول ، ئىسمى: "باھا"}); const quant = useWatch ({كونترول ، ئىسمى: "مىقدار"}); const taxRate = useWatch ({كونترول ، ئىسمى: "taxRate"}); const hasAccount = useWatch ({كونترول ، ئىسمى: "hasAccount"}); const satisfaction = useWatch ({control, name: "رازى"}); 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) || (step === 3 && total> = 100)

قايتىش.

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

Subtotal: {subtotal}
باج: {باج}
ئومۇمىي: {ئومۇمىي}
)}

{قەدەم === 2 && (<> <تاللاش {... تىزىملىتىڭ ("hasAccount")}> <تاللاش قىممىتى = "ھەئە"> ھەئە <تاللاش قىممىتى = "ياق"> ياق

{hasAccount === "ھەئە" && (<> <كىرگۈزۈش {... تىزىملىتىڭ ("ئىشلەتكۈچى ئىسمى")} placeholder = "ئىشلەتكۈچى ئىسمى" /> <كىرگۈزۈش {... تىزىملىتىڭ ("پارول")} placeholder = "پارول" /> )}

{رازى> = 4 && (