ບົດຄວາມນີ້ແມ່ນໄດ້ຮັບການສະຫນັບສະຫນູນໂດຍ SurveyJS ມີຕົວແບບທາງດ້ານຈິດໃຈທີ່ຜູ້ພັດທະນາ React ສ່ວນໃຫຍ່ແບ່ງປັນໂດຍບໍ່ເຄີຍສົນທະນາມັນອອກມາດັງໆ. ແບບຟອມນັ້ນຄວນເປັນອົງປະກອບສະເໝີ. ນີ້ຫມາຍຄວາມວ່າ stack ເຊັ່ນ:
ແບບຟອມ React Hook ສໍາລັບລັດທ້ອງຖິ່ນ (ການສະແດງຄືນໃຫມ່ຫນ້ອຍທີ່ສຸດ, ການລົງທະບຽນພາກສະຫນາມ ergonomic, ການໂຕ້ຕອບທີ່ຈໍາເປັນ). Zod ສໍາລັບການກວດສອບຄວາມຖືກຕ້ອງ (ການປ້ອນຂໍ້ມູນທີ່ຖືກຕ້ອງ, ການກວດສອບຂອບເຂດ, ການແຍກປະເພດທີ່ປອດໄພ). React Query ສໍາລັບ backend: ການຍື່ນສະເຫນີ, retry, caching, server sync, ແລະອື່ນໆ.
ແລະສໍາລັບຮູບແບບສ່ວນໃຫຍ່ — ຫນ້າຈໍເຂົ້າສູ່ລະບົບຂອງທ່ານ, ຫນ້າການຕັ້ງຄ່າຂອງທ່ານ, CRUD modals ຂອງທ່ານ — ນີ້ເຮັດວຽກໄດ້ດີຫຼາຍ. ແຕ່ລະຊິ້ນເຮັດວຽກຂອງມັນ, ພວກມັນປະກອບຢ່າງສະອາດ, ແລະເຈົ້າສາມາດກ້າວໄປສູ່ສ່ວນຕ່າງໆຂອງແອັບພລິເຄຊັນຂອງເຈົ້າເຊິ່ງເຮັດໃຫ້ຜະລິດຕະພັນຂອງເຈົ້າແຕກຕ່າງກັນ. ແຕ່ທຸກໆຄັ້ງໃນຂະນະນັ້ນ, ແບບຟອມຈະເລີ່ມສະສົມສິ່ງຕ່າງໆ ເຊັ່ນ: ກົດລະບຽບການເບິ່ງເຫັນທີ່ຂຶ້ນກັບຄຳຕອບກ່ອນໜ້າ, ຫຼືຄ່າທີ່ມາຈາກສາມຊ່ອງຂໍ້ມູນ. ບາງທີແມ່ນແຕ່ຫນ້າທັງຫມົດທີ່ຄວນຈະຖືກຂ້າມຫຼືສະແດງໃຫ້ເຫັນໂດຍອີງໃສ່ຈໍານວນທັງຫມົດທີ່ແລ່ນ. ທ່ານຈັດການເງື່ອນໄຂທໍາອິດກັບ useWatch ແລະສາຂາ inline, ເຊິ່ງດີ. ຫຼັງຈາກນັ້ນ, ອື່ນ. ຫຼັງຈາກນັ້ນ, ທ່ານກໍາລັງເຂົ້າຫາ superRefine ເພື່ອເຂົ້າລະຫັດກົດລະບຽບຂ້າມພາກສະຫນາມທີ່ Zod schema ຂອງທ່ານບໍ່ສາມາດສະແດງອອກໃນແບບປົກກະຕິ. ຈາກນັ້ນ, ຂັ້ນຕອນການນໍາທາງເລີ່ມຮົ່ວໄຫຼຕາມເຫດຜົນທາງທຸລະກິດ. ໃນບາງຈຸດ, ທ່ານເບິ່ງສິ່ງທີ່ທ່ານໄດ້ສ້າງແລະຮັບຮູ້ວ່າແບບຟອມບໍ່ແມ່ນ UI ແທ້ໆ. ມັນເປັນຂະບວນການຕັດສິນໃຈຫຼາຍກວ່າ, ແລະຕົ້ນໄມ້ອົງປະກອບແມ່ນພຽງແຕ່ບ່ອນທີ່ທ່ານໄດ້ເກີດຂຶ້ນເພື່ອເກັບຮັກສາມັນ. ນີ້ແມ່ນບ່ອນທີ່ຂ້ອຍຄິດວ່າຕົວແບບທາງຈິດສໍາລັບແບບຟອມໃນ React ທໍາລາຍ, ແລະມັນກໍ່ບໍ່ມີໃຜຜິດ. RHF + Zod stack ແມ່ນດີເລີດໃນສິ່ງທີ່ມັນຖືກອອກແບບມາສໍາລັບ. ບັນຫາແມ່ນວ່າພວກເຮົາມີແນວໂນ້ມທີ່ຈະສືບຕໍ່ໃຊ້ມັນຜ່ານຈຸດທີ່ບໍ່ມີຕົວຕົນຂອງມັນກົງກັບບັນຫາເພາະວ່າທາງເລືອກດັ່ງກ່າວຮຽກຮ້ອງໃຫ້ມີວິທີການຄິດທີ່ແຕກຕ່າງກັນກ່ຽວກັບຮູບແບບທັງຫມົດ. ບົດຄວາມນີ້ແມ່ນກ່ຽວກັບທາງເລືອກນັ້ນ. ເພື່ອສະແດງສິ່ງນີ້, ພວກເຮົາຈະສ້າງແບບຟອມຫຼາຍຂັ້ນຕອນດຽວກັນສອງຄັ້ງ:
ດ້ວຍແບບຟອມ React Hook + Zod ທີ່ມີສາຍເພື່ອຕອບຄໍາຖາມສໍາລັບການຍື່ນສະເຫນີ, ດ້ວຍ SurveyJS, ເຊິ່ງປະຕິບັດແບບຟອມເປັນຂໍ້ມູນ - ຮູບແບບ JSON ງ່າຍໆ - ແທນທີ່ຈະເປັນຕົ້ນໄມ້ອົງປະກອບ.
ຄວາມຕ້ອງການດຽວກັນ, ເຫດຜົນຕາມເງື່ອນໄຂດຽວກັນ, ການໂທ API ດຽວກັນໃນຕອນທ້າຍຂອງ. ຫຼັງຈາກນັ້ນ, ພວກເຮົາຈະວາງແຜນທີ່ແນ່ນອນວ່າສິ່ງທີ່ຍ້າຍແລະສິ່ງທີ່ຢູ່, ແລະວາງວິທີການປະຕິບັດເພື່ອຕັດສິນໃຈວ່າຕົວແບບໃດທີ່ເຈົ້າຄວນໃຊ້, ແລະເວລາໃດ. ແບບຟອມທີ່ພວກເຮົາສ້າງ:
ແບບຟອມນີ້ຈະໃຊ້ຂັ້ນຕອນ 4 ຂັ້ນຕອນ: ຂັ້ນຕອນທີ 1: ລາຍລະອຽດ
ຊື່ (ຕ້ອງການ), ອີເມວ (ຕ້ອງການ, ຮູບແບບທີ່ຖືກຕ້ອງ).
ຂັ້ນຕອນທີ 2: ຄໍາສັ່ງ
ລາຄາຫົວໜ່ວຍ, ປະລິມານ, ອັດຕາພາສີ, ໄດ້ມາຈາກ: ທັງໝົດຍ່ອຍ, ພາສີ, ທັງໝົດ.
ຂັ້ນຕອນທີ 3: ບັນຊີ & ຄໍາຕິຊົມ
ເຈົ້າມີບັນຊີບໍ? (ແມ່ນ/ບໍ່) ຖ້າແມ່ນ → ຊື່ຜູ້ໃຊ້ + ລະຫັດຜ່ານ, ທັງສອງຕ້ອງການ. ຖ້າບໍ່ແມ່ນ → ອີເມວຖືກເກັບກຳແລ້ວໃນຂັ້ນຕອນທີ 1.
ຄະແນນຄວາມພໍໃຈ (1–5) ຖ້າ ≥ 4 → ຖາມ “ເຈົ້າມັກຫຍັງ?” ຖ້າ ≤ 2 → ຖາມ “ພວກເຮົາສາມາດປັບປຸງຫຍັງໄດ້?”
ຂັ້ນຕອນທີ 4: ທົບທວນຄືນ
ພຽງແຕ່ປະກົດວ່າຈໍານວນທັງຫມົດ >= 100 ການຍື່ນສະເຫນີສຸດທ້າຍ.
ນີ້ບໍ່ແມ່ນທີ່ສຸດ. ແຕ່ມັນພຽງພໍທີ່ຈະສະແດງຄວາມແຕກຕ່າງທາງສະຖາປັດຕະຍະກໍາ. ສ່ວນທີ 1: Component-Driven (React Hook Form + Zod) ການຕິດຕັ້ງ npm ຕິດຕັ້ງ react-hook-form zod @hookform/resolvers @tanstack/react-query
Zod Schema ໃຫ້ເລີ່ມຕົ້ນດ້ວຍ Zod schema, ເພາະວ່າມັນມັກຈະເປັນບ່ອນທີ່ຮູບຮ່າງຂອງແບບຟອມຖືກສ້າງຕັ້ງຂຶ້ນ. ສໍາລັບສອງຂັ້ນຕອນທໍາອິດ - ລາຍລະອຽດສ່ວນບຸກຄົນແລະການປ້ອນຂໍ້ມູນຄໍາສັ່ງ - ທຸກສິ່ງທຸກຢ່າງແມ່ນກົງໄປກົງມາ: ສະຕິງທີ່ຕ້ອງການ, ຕົວເລກທີ່ມີຕໍາ່ສຸດທີ່, ແລະ enum. ສ່ວນທີ່ຫນ້າສົນໃຈເລີ່ມຕົ້ນເມື່ອທ່ານພະຍາຍາມສະແດງກົດລະບຽບທີ່ມີເງື່ອນໄຂ.
ນໍາເຂົ້າ { z } ຈາກ "zod";
export const formSchema = z.object({ firstName: z.string().min(1, "Required"), email: z.string().email("ອີເມລ໌ບໍ່ຖືກຕ້ອງ"), price: z.number().min(0), quantity: z.number().min(1), taxRate: z.number(), hasAccount: z.enum", "username:" (") ". z.string().optional(), ລະຫັດຜ່ານ: z.string().optional(), ຄວາມພໍໃຈ: z.number().min(1.max(5), positiveFeedback: z.string().optional(), improvementFeedback: z.string().optional(),}).superRefine((data, ctx) => { if (data=hasAccount) =data.hasAccount ctx.addIssue({ code: "custom", path: ["username"], message: "required" }); } if (!data.password || data.password.length < 6) { ctx.addIssue({ code: "custom", path: ["password"], message: "Min}); 6" ຕົວອັກສອນ.
if (data.satisfaction >= 4 && !data.positiveFeedback) { ctx.addIssue({ code: "custom", path: ["positiveFeedback"], message: "Please share what you liked" }); }
ຖ້າ (data.satisfaction <= 2 && !data.improvementFeedback) { ctx.addIssue({ code: "custom", ເສັ້ນທາງ:["improvementFeedback"], ຂໍ້ຄວາມ: "ກະລຸນາບອກພວກເຮົາສິ່ງທີ່ຈະປັບປຸງ" }); } });
ປະເພດສົ່ງອອກ FormData = z.infer
ສັງເກດເຫັນວ່າຊື່ຜູ້ໃຊ້ແລະລະຫັດຜ່ານຖືກພິມເປັນທາງເລືອກ () ເຖິງແມ່ນວ່າພວກເຂົາຕ້ອງການຕາມເງື່ອນໄຂເພາະວ່າ schema ລະດັບປະເພດ Zod ອະທິບາຍຮູບຮ່າງຂອງວັດຖຸ, ບໍ່ແມ່ນກົດລະບຽບທີ່ປົກຄອງໃນເວລາທີ່ພາກສະຫນາມສໍາຄັນ. ຂໍ້ກໍານົດທີ່ມີເງື່ອນໄຂຕ້ອງອາໄສຢູ່ພາຍໃນ superRefine, ເຊິ່ງດໍາເນີນການຫຼັງຈາກຮູບຮ່າງຖືກກວດສອບແລະສາມາດເຂົ້າເຖິງວັດຖຸເຕັມ. ການແຍກຕົວນັ້ນບໍ່ແມ່ນຂໍ້ບົກພ່ອງ; ມັນເປັນພຽງແຕ່ສິ່ງທີ່ເຄື່ອງມືໄດ້ຖືກອອກແບບສໍາລັບ: superRefine ແມ່ນບ່ອນທີ່ເຫດຜົນຂ້າມພາກສະຫນາມໄປໃນເວລາທີ່ມັນບໍ່ສາມາດສະແດງອອກໃນໂຄງສ້າງ schema ຕົວຂອງມັນເອງ. ສິ່ງທີ່ໂດດເດັ່ນໃນນີ້ແມ່ນສິ່ງທີ່ schema ນີ້ບໍ່ໄດ້ສະແດງອອກ. ມັນບໍ່ມີແນວຄວາມຄິດຂອງຫນ້າ, ບໍ່ມີແນວຄວາມຄິດຂອງທົ່ງນາທີ່ສັງເກດເຫັນຢູ່ໃນຈຸດໃດ, ແລະບໍ່ມີແນວຄວາມຄິດຂອງການນໍາທາງ. ທັງຫມົດນັ້ນຈະອາໄສຢູ່ບ່ອນອື່ນ. ອົງປະກອບແບບຟອມ
ນໍາເຂົ້າ { useForm, useWatch } ຈາກ "react-hook-form"; ນໍາເຂົ້າ { zodResolver } ຈາກ "@hookform/resolvers/zod"; ນໍາເຂົ້າ { useMutation } ຈາກ "@tanstack/react-query"; ນໍາເຂົ້າ { useState, useMemo } ຈາກ "react"; ນໍາເຂົ້າ { form./schema, ປະເພດ};
const STEPS = ["ລາຍລະອຽດ", "ຄໍາສັ່ງ", "ບັນຊີ", "ທົບທວນ"];
ປະເພດ OrderPayload = FormData & { subtotal: number; tax: ຈໍານວນ; ທັງໝົດ: ຈໍານວນ };
ຟັງຊັນສົ່ງອອກ RHFMultiStepForm() { const [ຂັ້ນຕອນ, setStep] = useState(0);
const mutation = useMutation({ mutationFn: async (ຄ່າຈ່າຍ: OrderPayload) => { const res = ລໍຖ້າ fetch("/api/orders", { ວິທີການ: "POST", headers: { "Content-Type": "application/json" }, ເນື້ອໃນ: JSON.stringify(payload), }); ຖ້າ (!res.ok) ຖິ້ມ Error ໃໝ່ ("ບໍ່ສາມາດສົ່ງ"); ກັບຄືນ res.json(); }, });
const { ລົງທະບຽນ, ຄວບຄຸມ, handleSubmit, formState: { errors }, } = useForm
return (
);}ເບິ່ງ Pen SurveyJS-03-RHF [forked] ໂດຍ sixthextinction. ມີຫຼາຍຢ່າງທີ່ເກີດຂື້ນຢູ່ທີ່ນີ້, ແລະມັນສົມຄວນທີ່ຈະຊ້າລົງເພື່ອສັງເກດເຫັນວ່າສິ່ງທີ່ສິ້ນສຸດລົງ.
ມູນຄ່າທີ່ມາຈາກ - ຈໍານວນຍ່ອຍ, ພາສີ, ຈໍານວນທັງຫມົດ - ແມ່ນຄໍານວນໃນອົງປະກອບຜ່ານ useWatch ແລະ useMemo ເພາະວ່າພວກມັນຂຶ້ນກັບຄ່າພາກສະຫນາມສົດແລະບໍ່ມີສະຖານທີ່ທໍາມະຊາດອື່ນສໍາລັບພວກມັນ. ກົດລະບຽບການເບິ່ງເຫັນສໍາລັບຊື່ຜູ້ໃຊ້, ລະຫັດຜ່ານ, positiveFeedback, ແລະການປັບປຸງ Feedback ດໍາລົງຊີວິດຢູ່ໃນ JSX ເປັນເງື່ອນໄຂໃນແຖວ. ເຫດຜົນຂອງການຂ້າມຂັ້ນຕອນ — ຫນ້າທີ່ທົບທວນພຽງແຕ່ປາກົດເມື່ອຈໍານວນທັງຫມົດ >= 100 — ໄດ້ຖືກຝັງເຂົ້າໄປໃນຕົວແປສະແດງໃຫ້ເຫັນການຍື່ນສະເຫນີແລະເງື່ອນໄຂການສະແດງຢູ່ໃນຂັ້ນຕອນທີ 3. Navigation ຕົວຂອງມັນເອງແມ່ນພຽງແຕ່ຕົວนับ useState ທີ່ພວກເຮົາກໍາລັງເພີ່ມຂຶ້ນດ້ວຍຕົນເອງ. React Query ຈັດການການລອງຄືນໃຫມ່, caching, ແລະ invalidation. ແບບຟອມພຽງແຕ່ໂທຫາ mutation.mutate ດ້ວຍຂໍ້ມູນທີ່ຖືກຕ້ອງ.
ບໍ່ມີອັນໃດອັນນີ້ແມ່ນຜິດພາດ, perse. ນີ້ຍັງເປັນ React idiomatic, ແລະອົງປະກອບແມ່ນຂ້ອນຂ້າງປະຕິບັດຍ້ອນວິທີການ RHF isolates re-renders. ແຕ່ຖ້າທ່ານຕ້ອງມອບເລື່ອງນີ້ໃຫ້ກັບຜູ້ທີ່ບໍ່ໄດ້ຂຽນມັນແລະຂໍໃຫ້ພວກເຂົາອະທິບາຍພາຍໃຕ້ເງື່ອນໄຂໃດທີ່ຫນ້າເວັບທົບທວນປາກົດ, ພວກເຂົາຈະຕ້ອງຕິດຕາມເບິ່ງການສະແດງອອກ, ເງື່ອນໄຂການສະແດງຂັ້ນຕອນ 3, ແລະເຫດຜົນຂອງປຸ່ມ nav - ສາມບ່ອນແຍກຕ່າງຫາກ - ເພື່ອສ້າງກົດລະບຽບທີ່ສາມາດລະບຸໄວ້ໃນເສັ້ນດຽວ. ແບບຟອມເຮັດວຽກ, ແມ່ນແລ້ວ, ແຕ່ພຶດຕິກໍາບໍ່ສາມາດກວດສອບໄດ້ຢ່າງແທ້ຈິງເປັນລະບົບ. ມັນຕ້ອງໄດ້ຮັບການປະຕິບັດທາງຈິດໃຈ. ສິ່ງທີ່ສໍາຄັນກວ່ານັ້ນ, ການປ່ຽນແປງມັນຮຽກຮ້ອງໃຫ້ມີການມີສ່ວນຮ່ວມດ້ານວິສະວະກໍາ. ເຖິງແມ່ນວ່າການປັບຕົວເລັກໆນ້ອຍໆ, ເຊັ່ນການປັບຕົວເມື່ອຂັ້ນຕອນການທົບທວນຄືນສະແດງໃຫ້ເຫັນເຖິງ, ຫມາຍຄວາມວ່າການແກ້ໄຂອົງປະກອບ, ການປັບປຸງການກວດສອບ, ເປີດການຮ້ອງຂໍດຶງ, ລໍຖ້າການທົບທວນຄືນ, ແລະນໍາໃຊ້ອີກເທື່ອຫນຶ່ງ. ສ່ວນທີ 2: ການຂັບເຄື່ອນແບບແຜນ (SurveyJS) ຕອນນີ້ໃຫ້ສ້າງກະແສດຽວກັນໂດຍໃຊ້ schema. ການຕິດຕັ້ງ npm ຕິດຕັ້ງ survey-core survey-react-ui @tanstack/react-query
survey-coreThe MIT-licensed platform-independent runtime engine that powers of SurveyJS’s form rendering — ສ່ວນທີ່ພວກເຮົາສົນໃຈກ່ຽວກັບການນີ້. ມັນໃຊ້ JSON schema, ສ້າງແບບຈໍາລອງພາຍໃນຈາກມັນ, ແລະຈັດການທຸກສິ່ງທີ່ບໍ່ດັ່ງນັ້ນຈະຢູ່ໃນອົງປະກອບ React ຂອງທ່ານ: ການປະເມີນການສະແດງອອກຂອງການເບິ່ງເຫັນ, ການຄິດໄລ່ມູນຄ່າທີ່ມາຈາກ, ການຄຸ້ມຄອງສະຖານະຂອງຫນ້າ, ການຕິດຕາມການກວດສອບແລະການຕັດສິນໃຈວ່າ "ສົມບູນ" ຫມາຍຄວາມວ່າຫນ້າໃດຖືກສະແດງ.
survey-react-uiThe UI / rendering layer ທີ່ເຊື່ອມຕໍ່ແບບຈໍາລອງນັ້ນກັບ React. ມັນເປັນສິ່ງຈໍາເປັນ
ຮ່ວມກັນ, ພວກມັນໃຫ້ທ່ານເປັນ runtime ແບບຟອມຫຼາຍຫນ້າທີ່ເປັນປະໂຫຍດຢ່າງເຕັມທີ່ໂດຍບໍ່ຕ້ອງຂຽນເສັ້ນດຽວຂອງການໄຫຼຄວບຄຸມ. ຮູບແບບ schema ຕົວຂອງມັນເອງແມ່ນ, ດັ່ງທີ່ໄດ້ກ່າວກ່ອນຫນ້ານີ້, ພຽງແຕ່ເປັນ JSON - ບໍ່ມີ DSL ຫຼືສິ່ງໃດໆທີ່ເປັນເຈົ້າຂອງ. ທ່ານສາມາດ inline ມັນ, ນໍາເຂົ້າຈາກໄຟລ໌, ເອົາມັນຈາກ API, ຫຼືເກັບຮັກສາໄວ້ໃນຖັນຖານຂໍ້ມູນແລະໃຫ້ມັນໃນເວລາແລ່ນ. ແບບຟອມດຽວກັນ, ເປັນຂໍ້ມູນ ນີ້ແມ່ນຮູບແບບດຽວກັນ, ເວລານີ້ສະແດງອອກເປັນວັດຖຸ JSON. schema ກໍານົດທຸກສິ່ງທຸກຢ່າງ: ໂຄງສ້າງ, ການກວດສອບ, ກົດລະບຽບການເບິ່ງເຫັນ, ການຄິດໄລ່ທີ່ມາຈາກ, ການນໍາທາງຫນ້າ - ແລະມອບມັນໃຫ້ກັບຕົວແບບທີ່ປະເມີນມັນໃນເວລາແລ່ນ. ນີ້ແມ່ນສິ່ງທີ່ມີລັກສະນະເຕັມທີ່:
export const surveySchema = { title: "Order Flow", showProgressBar: "top", pages: [ { name: "details", ອົງປະກອບ: [ { type: "text", name: "firstName", isRequired: true }, { type: "text", name: "email", inputType: "email", isRequired: [valid" type: valid] } ] }, { name: "order", ອົງປະກອບ: [ { type: "text", ຊື່: "price", inputType: "number", defaultValue: 0 }, { type: "text", name: "quantity", inputType: "number", defaultValue: 1 }, { type: "dropdown",name: "taxRate", defaultValue: 0.1, choices: [ { value: 0.05, text: "5%" }, { value: 0.1, text: "10%" }, { value: 0.15, text: "15%" } ] }, { type: "expression", name: "subtotal", expression: "subtotal", {type: "expression", name: "subtotal", "expression", ຊື່: "tax", ສະແດງອອກ: "{subtotal} {taxRate}" }, { type: "expression", name: "total", expression: "{subtotal} + {tax}" } ] }, { name: "account", ອົງປະກອບ: [ { type: "radiogroup", name: "hasAccount", ທາງເລືອກ, {" type: "Yes", ທາງເລືອກ: {"Yes" "username", visibleIf: "{hasAccount} = 'Yes'", isRequired: true }, { type: "text", name: "password", inputType: "password", visibleIf: "{hasAccount} = 'Yes'", isRequired: true, validators: [{ type: "text", name: "password", inputType: "password", visibleIf: "{hasAccount} = 'Yes'", isRequired: true, validators: [{ type: "text" , minLength: 6 ຕົວອັກສອນ: "} } "rating", ຊື່: "ຄວາມພໍໃຈ", rateMin: 1, rateMax: 5 }, { type: "comment", name: "positiveFeedback", visibleIf: "{satisfaction} >= 4" }, { type: "comment", name: "improvementFeedback", visibleIf: "{satisfaction} <= 2" } ]=viewto tal : {0}: {0} [] } ]};
ປຽບທຽບນີ້ກັບລຸ້ນ RHF ໃນເວລາສັ້ນໆ.
ບລັອກ superRefine ທີ່ຕ້ອງການຊື່ຜູ້ໃຊ້ແລະລະຫັດຜ່ານແມ່ນຫມົດໄປ. visibleIf: "{hasAccount} = 'Yes'" ລວມກັບ isRequired: true handles ທັງສອງຄວາມກັງວົນຮ່ວມກັນ, ໃນພາກສະຫນາມຕົວມັນເອງ, ບ່ອນທີ່ທ່ານຄາດຫວັງວ່າຈະຊອກຫາພວກມັນ. ລະບົບຕ່ອງໂສ້ useWatch + useMemo ທີ່ຄຳນວນທັງໝົດຍ່ອຍ, ອາກອນ, ແລະທັງໝົດຖືກແທນທີ່ດ້ວຍສາມຊ່ອງຂໍ້ມູນທີ່ອ້າງອີງເຊິ່ງກັນແລະກັນດ້ວຍຊື່. ເງື່ອນໄຂຂອງຫນ້າການທົບທວນຄືນ, ເຊິ່ງໃນສະບັບ RHF ແມ່ນ reconstructable ພຽງແຕ່ໂດຍການ tracing ຜ່ານ showSubmit, ຂັ້ນຕອນ 3 render ສາຂາ. ແລະສຸດທ້າຍ, ເຫດຜົນຂອງປຸ່ມ nav ເປັນຄຸນສົມບັດ visibleIf ດຽວຢູ່ໃນວັດຖຸຂອງຫນ້າ.
ເຫດຜົນດຽວກັນແມ່ນຢູ່ທີ່ນັ້ນ. ມັນເປັນພຽງແຕ່ວ່າ schema ເຮັດໃຫ້ມັນເປັນບ່ອນຢູ່ບ່ອນທີ່ມັນສັງເກດເຫັນຢູ່ໃນຄວາມໂດດດ່ຽວ, ແທນທີ່ຈະແຜ່ລາມໄປທົ່ວອົງປະກອບ. ນອກຈາກນັ້ນ, ໃຫ້ສັງເກດວ່າ schema ໃຊ້ປະເພດ: 'ສະແດງອອກ' ສໍາລັບຈໍານວນຍ່ອຍ, ພາສີ, ແລະຈໍານວນທັງຫມົດ. ການສະແດງອອກແມ່ນອ່ານເທົ່ານັ້ນ ແລະໃຊ້ເປັນສ່ວນໃຫຍ່ເພື່ອສະແດງຄ່າທີ່ຄຳນວນໄດ້. SurveyJS ຍັງສະຫນັບສະຫນູນປະເພດ: 'html' ສໍາລັບເນື້ອຫາທີ່ສະຖິດ, ແຕ່ສໍາລັບຄ່າທີ່ຄິດໄລ່, ການສະແດງອອກແມ່ນທາງເລືອກທີ່ເຫມາະສົມ. ໃນປັດຈຸບັນສໍາລັບດ້ານ React. ການສະແດງແລະການຍື່ນສະເຫນີ ງ່າຍດາຍຫຼາຍ. Wire onComplete ກັບ API ຂອງທ່ານດ້ວຍວິທີດຽວກັນ — ໂດຍຜ່ານ useMutation ຫຼື fetch ທໍາມະດາ:
ນໍາເຂົ້າ { useState, useEffect, useRef } ຈາກ "react";ນໍາເຂົ້າ { useMutation } ຈາກ "@tanstack/react-query";ນໍາເຂົ້າ { Model } ຈາກ "survey-core";ນໍາເຂົ້າ { Survey } ຈາກ "survey-react-ui";ນໍາເຂົ້າ "survey-core/survey";
ຟັງຊັນການສົ່ງອອກ SurveyForm() { const [model] = useState(() => new Model(surveySchema));
const mutation = useMutation({ mutationFn: async (ຂໍ້ມູນ) => { const res = ລໍຖ້າ fetch("/api/orders", { ວິທີການ: "POST", headers: { "Content-Type": "application/json" }, ເນື້ອໃນ: JSON.stringify(data), }); ຖ້າ (!res.ok) ຖິ້ມ Error ໃໝ່ ("ບໍ່ສາມາດສົ່ງ"); ກັບຄືນ res.json(); }, });
const mutationRef = useRef(ການກາຍພັນ); mutationRef.current = ການກາຍພັນ; useEffect(() => { const handler = (sender) => mutationRef.current.mutate(sender.data); model.onComplete.add(handler); return () => model.onComplete.remove(handler); }, [model]); // ref ຫຼີກເວັ້ນການລົງທະບຽນໃຫມ່ handler ທຸກໆ render (ການປ່ຽນແປງຕົວຕົນຂອງວັດຖຸທີ່ກາຍພັນ)
ກັບຄືນ (
<>
ເບິ່ງ Pen SurveyJS-03-SurveyJS [forked] ໂດຍ sixthextinction.
onComplete fires ເມື່ອຜູ້ໃຊ້ໄປຮອດຈຸດສຸດທ້າຍຂອງຫນ້າທີ່ສັງເກດເຫັນສຸດທ້າຍ. ດັ່ງນັ້ນ, ຖ້າຈໍານວນທັງຫມົດບໍ່ເຄີຍຂ້າມ 100 ແລະຫນ້າທົບທວນຖືກຂ້າມ, ມັນຍັງຖືກໄຟໄຫມ້ຢ່າງຖືກຕ້ອງເພາະວ່າ SurveyJS ປະເມີນການເບິ່ງເຫັນກ່ອນທີ່ຈະຕັດສິນໃຈວ່າ "ຫນ້າສຸດທ້າຍ" ຫມາຍຄວາມວ່າແນວໃດ. ຫຼັງຈາກນັ້ນ, sender.data ປະກອບດ້ວຍຄໍາຕອບທັງຫມົດພ້ອມກັບຄ່າທີ່ຄິດໄລ່ (ລວມຍ່ອຍ, ພາສີ, ຈໍານວນທັງຫມົດ) ເປັນຊ່ອງຂໍ້ມູນຊັ້ນທໍາອິດ, ດັ່ງນັ້ນ API payload ແມ່ນຄືກັນກັບສິ່ງທີ່ RHF ຮຸ່ນທີ່ປະກອບດ້ວຍຕົນເອງໃນ onSubmit. ໄດ້ຮູບແບບ mutationRef ແມ່ນອັນດຽວກັນທີ່ເຈົ້າຈະໄປເຖິງບ່ອນໃດກໍໄດ້ທີ່ເຈົ້າຕ້ອງການຕົວຈັດການເຫດການທີ່ໝັ້ນຄົງຕໍ່ກັບມູນຄ່າທີ່ປ່ຽນແປງໃນທຸກການສະແດງຜົນ — ບໍ່ມີຫຍັງສະເພາະຂອງ SurveyJS ກ່ຽວກັບມັນ.
ອົງປະກອບ React ບໍ່ມີເຫດຜົນທາງທຸລະກິດອີກຕໍ່ໄປ. ບໍ່ມີ useWatch, ບໍ່ມີ JSX ທີ່ມີເງື່ອນໄຂ, ບໍ່ມີຕົວນັບຂັ້ນຕອນ, ບໍ່ມີຕ່ອງໂສ້ useMemo, ບໍ່ມີ superRefine. React ກໍາລັງເຮັດສິ່ງທີ່ມັນດີຢູ່ໃນຕົວຈິງ: ການສະແດງອົງປະກອບແລະສາຍມັນໄປຫາການໂທ API. ສິ່ງທີ່ຍ້າຍອອກຈາກປະຕິກິລິຍາ?
ຄວາມກັງວົນ RHF Stack ການສໍາຫຼວດJS ການເບິ່ງເຫັນ ສາຂາ JSX ເຫັນໄດ້ຖ້າ ຄ່າທີ່ມາຈາກ useWatch / useMemo ການສະແດງອອກ ກົດລະບຽບຂ້າມພາກສະຫນາມ superRefine ເງື່ອນໄຂ Schema ການນໍາທາງ ສະຖານະຂັ້ນຕອນ ໜ້າເບິ່ງເຫັນຖ້າ ສະຖານທີ່ກົດລະບຽບ ແຈກຢາຍໃນທົ່ວໄຟລ໌ ສູນກາງໃນ schema
ສິ່ງທີ່ຢູ່ໃນ React ແມ່ນຮູບແບບ, ຄໍເຕົ້າໄຂ່ທີ່, ສາຍສົ່ງ, ແລະການລວມຕົວຂອງແອັບຯ, ເຊິ່ງຫມາຍຄວາມວ່າ, ສິ່ງທີ່ React ຖືກອອກແບບມາສໍາລັບຕົວຈິງ. ທຸກສິ່ງທຸກຢ່າງອື່ນໄດ້ຍ້າຍໄປຢູ່ໃນ schema, ແລະເນື່ອງຈາກວ່າ schema ແມ່ນພຽງແຕ່ວັດຖຸ JSON, ມັນສາມາດຖືກເກັບໄວ້ໃນຖານຂໍ້ມູນ, ສະບັບພາສາເອກະລາດຂອງລະຫັດຄໍາຮ້ອງສະຫມັກຂອງທ່ານ, ຫຼືແກ້ໄຂໂດຍຜ່ານເຄື່ອງມືພາຍໃນໂດຍບໍ່ຈໍາເປັນຕ້ອງມີການຕິດຕັ້ງ. ຜູ້ຈັດການຜະລິດຕະພັນທີ່ຕ້ອງການປ່ຽນຂອບເຂດທີ່ກະຕຸ້ນໃຫ້ຫນ້າທົບທວນສາມາດເຮັດແນວນັ້ນໄດ້ໂດຍບໍ່ຕ້ອງສໍາຜັດກັບອົງປະກອບ. ນັ້ນແມ່ນຄວາມແຕກຕ່າງດ້ານການປະຕິບັດງານທີ່ມີຄວາມຫມາຍສໍາລັບທີມງານທີ່ພຶດຕິກໍາຂອງແບບຟອມພັດທະນາເລື້ອຍໆແລະບໍ່ໄດ້ຂັບເຄື່ອນໂດຍວິສະວະກອນສະເຫມີ. ເມື່ອໃດທີ່ຈະໃຊ້ແຕ່ລະວິທີ? ນີ້ແມ່ນກົດລະບຽບທີ່ດີທີ່ເຮັດວຽກສໍາລັບຂ້ອຍ: ຈິນຕະນາການລຶບແບບຟອມທັງຫມົດ. ເຈົ້າຈະສູນເສຍຫຍັງ?
ຖ້າມັນເປັນຫນ້າຈໍ, ທ່ານຕ້ອງການແບບຟອມທີ່ຂັບເຄື່ອນໂດຍອົງປະກອບ. ຖ້າມັນເປັນເຫດຜົນທາງທຸລະກິດ, ເຊັ່ນ: ຂອບເຂດ, ກົດລະບຽບການແຍກ, ແລະຂໍ້ກໍານົດເງື່ອນໄຂທີ່ເຂົ້າລະຫັດການຕັດສິນໃຈທີ່ແທ້ຈິງ, ທ່ານຕ້ອງການເຄື່ອງຈັກ schema.
ເຊັ່ນດຽວກັນ, ຖ້າການປ່ຽນແປງທີ່ເຂົ້າມາໃນວິທີການຂອງເຈົ້າສ່ວນໃຫຍ່ແມ່ນກ່ຽວກັບປ້າຍຊື່, ທົ່ງນາ, ແລະຮູບແບບ, RHF ຈະໃຫ້ບໍລິການທ່ານດີ. ຖ້າພວກເຂົາກ່ຽວກັບເງື່ອນໄຂ, ຜົນໄດ້ຮັບ, ແລະກົດລະບຽບທີ່ ops ຫຼືທີມງານທາງດ້ານກົດຫມາຍຂອງທ່ານອາດຈະຕ້ອງປັບຕົວໃນຕອນບ່າຍວັນອັງຄານໂດຍບໍ່ມີການຍື່ນປີ້, ຮູບແບບ schema ກັບ SurveyJS ແມ່ນເຫມາະສົມກວ່າທີ່ຊື່ສັດ. ທັງສອງວິທີການນີ້ແມ່ນບໍ່ໄດ້ຢູ່ໃນການແຂ່ງຂັນກັບກັນແລະກັນ. ພວກເຂົາແກ້ໄຂບັນຫາປະເພດຕ່າງໆ, ແລະຄວາມຜິດພາດທີ່ຄວນຫລີກລ້ຽງແມ່ນຄວາມບໍ່ສົມດຸນກັບນ້ໍາຫນັກຂອງເຫດຜົນ - ການປະຕິບັດລະບົບກົດລະບຽບຄືກັບອົງປະກອບເພາະວ່ານັ້ນແມ່ນເຄື່ອງມືທີ່ຄຸ້ນເຄີຍ, ຫຼືການເຂົ້າຫາເຄື່ອງຈັກນະໂຍບາຍເພາະວ່າແບບຟອມໄດ້ເຕີບໂຕເຖິງສາມຂັ້ນຕອນແລະໄດ້ຮັບພາກສະຫນາມທີ່ມີເງື່ອນໄຂ. ຮູບແບບທີ່ພວກເຮົາສ້າງຢູ່ນີ້ຕັ້ງຢູ່ໃກ້ກັບເຂດແດນໂດຍເຈດຕະນາ, ສະລັບສັບຊ້ອນພຽງພໍທີ່ຈະເປີດເຜີຍຄວາມແຕກຕ່າງແຕ່ບໍ່ຮ້າຍແຮງທີ່ສຸດທີ່ການປຽບທຽບມີຄວາມຮູ້ສຶກເຄັ່ງຄັດ. ຮູບແບບທີ່ແທ້ຈິງສ່ວນໃຫຍ່ທີ່ໄດ້ຮັບຄວາມບໍ່ສະດວກໃນ codebase ຂອງທ່ານອາດຈະນັ່ງຢູ່ໃກ້ກັບຊາຍແດນດຽວກັນນັ້ນ, ແລະຄໍາຖາມແມ່ນປົກກະຕິແລ້ວວ່າໃຜໄດ້ຕັ້ງຊື່ສິ່ງທີ່ພວກເຂົາເປັນ. ໃຊ້ React Hook Form + Zod ເມື່ອ:
ແບບຟອມແມ່ນ CRUD-oriented; Logic ແມ່ນຕື້ນແລະ UI-driven; ວິສະວະກອນເປັນເຈົ້າຂອງພຶດຕິກໍາທັງຫມົດ; Backend ຍັງຄົງເປັນແຫຼ່ງຂອງຄວາມຈິງ.
ໃຊ້ SurveyJS ເມື່ອ:
ແບບຟອມເຂົ້າລະຫັດການຕັດສິນໃຈທາງທຸລະກິດ; ກົດລະບຽບພັດທະນາເປັນເອກະລາດຂອງ UI; ເຫດຜົນຕ້ອງເຫັນໄດ້, ສາມາດກວດສອບໄດ້, ຫຼືສະບັບ; ທີ່ບໍ່ແມ່ນວິສະວະກອນມີອິດທິພົນຕໍ່ພຶດຕິກໍາ; ແບບຟອມດຽວກັນຈະຕ້ອງແລ່ນຜ່ານຫຼາຍຫນ້າ.