এই লেখাটো SurveyJS ৰ পৃষ্ঠপোষকতাত লিখা হৈছে বেছিভাগ React ডেভেলপাৰে কেতিয়াও ডাঙৰকৈ আলোচনা নকৰাকৈ শ্বেয়াৰ কৰা এটা মানসিক মডেল আছে৷ যে ৰূপবোৰ সদায় উপাদান হোৱাৰ কথা। ইয়াৰ অৰ্থ হৈছে এটা ষ্টেক যেনে:
স্থানীয় অৱস্থাৰ বাবে ৰিএক্ট হুক ফৰ্ম (নূন্যতম পুনৰ ৰেণ্ডাৰ, এৰগ'নমিক ক্ষেত্ৰ পঞ্জীয়ন, আৱশ্যকীয় পাৰস্পৰিক ক্ৰিয়া)। বৈধকৰণৰ বাবে Zod (ইনপুট শুদ্ধতা, সীমা বৈধকৰণ, ধৰণ-নিৰাপদ বিশ্লেষণ)। বেকএণ্ডৰ বাবে React Query: দাখিল, পুনৰ চেষ্টা, কেচিং, চাৰ্ভাৰ ছিঙ্ক, ইত্যাদি।
আৰু ফৰ্মসমূহৰ বিপুল সংখ্যকৰ বাবে — আপোনাৰ লগইন পৰ্দাসমূহ, আপোনাৰ সংহতিসমূহ পৃষ্ঠাসমূহ, আপোনাৰ CRUD মডালসমূহ — ই সঁচাকৈয়ে ভাল কাম কৰে। প্ৰতিটো টুকুৰাই নিজৰ কাম কৰে, সিহঁতে পৰিষ্কাৰভাৱে ৰচনা কৰে, আৰু আপুনি আপোনাৰ এপ্লিকেচনৰ সেই অংশসমূহলৈ যাব পাৰে যিয়ে আপোনাৰ উৎপাদনক প্ৰকৃততে পৃথক কৰে। কিন্তু মাজে মাজে এটা ফৰ্মে আগৰ উত্তৰৰ ওপৰত নিৰ্ভৰশীল দৃশ্যমানতাৰ নিয়ম, বা তিনিটা ক্ষেত্ৰৰ মাজেৰে কেছকেড হোৱা ব্যুৎপন্ন মান আদি বস্তু জমা কৰিবলৈ আৰম্ভ কৰে। হয়তো আনকি সম্পূৰ্ণ পৃষ্ঠা যিবোৰ এৰিব লাগে বা চলি থকা মুঠৰ ওপৰত ভিত্তি কৰি দেখুৱাব লাগে। আপুনি প্ৰথম চৰ্তযুক্তক এটা useWatch আৰু এটা ইনলাইন শাখাৰ সৈতে নিয়ন্ত্ৰণ কৰে, যিটো ঠিকেই আছে। তাৰ পিছত আন এটা। তাৰ পিছত আপুনি superRefine ৰ বাবে আগবাঢ়িছে ক্ৰছ-ফিল্ড নিয়মসমূহ এনকোড কৰিবলৈ যিবোৰ আপোনাৰ Zod আঁচনিয়ে সাধাৰণভাৱে প্ৰকাশ কৰিব নোৱাৰে। তাৰ পিছত, ষ্টেপ নেভিগেচনে ব্যৱসায়িক যুক্তি লিক কৰিবলৈ আৰম্ভ কৰে। এটা সময়ত, আপুনি কি নিৰ্মাণ কৰিছে তাক চায় আৰু উপলব্ধি কৰে যে ফৰ্মখন আৰু প্ৰকৃততে UI নহয়। ই অধিক সিদ্ধান্ত প্ৰক্ৰিয়া, আৰু উপাদান গছটো আপুনি ইয়াক সংৰক্ষণ কৰা ঠাইতে আছে। এইখিনিতে মই ভাবো যে ৰিয়েক্টত ফৰ্মৰ বাবে মানসিক আৰ্হিটো ভাঙি যায়, আৰু সঁচাকৈয়ে ইয়াত কাৰো দোষ নাই। RHF + Zod ষ্টেক ইয়াক যিটোৰ বাবে ডিজাইন কৰা হৈছিল তাত উৎকৃষ্ট। বিষয়টো হ’ল আমি ইয়াক ইয়াৰ বিমূৰ্ততাই সমস্যাটোৰ সৈতে মিল থকা বিন্দুটোৰ ওপৰেৰে ব্যৱহাৰ কৰি থকাৰ প্ৰৱণতা ৰাখোঁ কাৰণ বিকল্পটোৰ বাবে ৰূপৰ বিষয়ে সম্পূৰ্ণৰূপে বেলেগ ধৰণৰ চিন্তা কৰাৰ প্ৰয়োজন। এই লেখাটো সেই বিকল্পৰ বিষয়ে। ইয়াক দেখুৱাবলৈ, আমি একেটা বহু-পদক্ষেপৰ ফৰ্ম দুবাৰ নিৰ্মাণ কৰিম:
React Hook Form + Zod জমা দিয়াৰ বাবে React Query লৈ তাঁৰযুক্ত, SurveyJS ৰ সৈতে, যি এটা প্ৰপত্ৰক তথ্য হিচাপে গণ্য কৰে — এটা সৰল JSON আঁচনি — এটা উপাদান বৃক্ষৰ পৰিবৰ্তে।
একে প্ৰয়োজনীয়তা, একে চৰ্তযুক্ত যুক্তি, শেষত একে এপিআই কল। তাৰ পিছত আমি কি স্থানান্তৰিত হ’ল আৰু কি থাকিল সেইটো সঠিকভাৱে মেপ কৰিম, আৰু আপুনি কোনটো মডেল ব্যৱহাৰ কৰিব লাগে, আৰু কেতিয়া ব্যৱহাৰ কৰিব লাগে সেইটো নিৰ্ণয় কৰাৰ এটা ব্যৱহাৰিক উপায় ৰাখিম৷ আমি নিৰ্মাণ কৰা ফৰ্মখন:
এই প্ৰপত্ৰত ৪-পদক্ষেপৰ প্ৰবাহ ব্যৱহাৰ কৰা হ'ব: স্তৰ ১: সবিশেষ
প্ৰথম নাম (প্ৰয়োজনীয়), ইমেইল (প্ৰয়োজনীয়, বৈধ বিন্যাস)।
২য় পদক্ষেপ: অৰ্ডাৰ কৰক
ইউনিটৰ মূল্য, পৰিমাণ, কৰ হাৰ, ব্যুৎপত্তি: উপমুঠ, কৰ, মুঠ।
স্তৰ ৩: একাউণ্ট আৰু মতামত
আপোনাৰ একাউণ্ট আছে নেকি? (হয়/নাই) যদি হয় → ব্যৱহাৰকাৰীৰ নাম + গুপ্তশব্দ, দুয়োটাৰ প্ৰয়োজন। যদি নাই → ইতিমধ্যে স্তৰ 1 ত সংগ্ৰহ কৰা ইমেইল।
সন্তুষ্টিৰ ৰেটিং (1–5) যদি ≥ 4 → সুধিব “আপুনি কি ভাল পাইছিল?” যদি ≤ 2 → সুধিব “আমি কি উন্নত কৰিব পাৰো?”
৪ৰ্থ স্তৰ: পুনৰীক্ষণ কৰক
কেৱল যদি মুঠ >= 100 হয় তেন্তেহে দেখা দিয়ে চূড়ান্ত জমা দিয়া।
এইটো চৰম নহয়। কিন্তু স্থাপত্যৰ পাৰ্থক্য উন্মোচন কৰিবলৈ ই যথেষ্ট৷ অংশ ১: উপাদান-চালিত (প্ৰতিক্ৰিয়া হুক ফৰ্ম + Zod) সংস্থাপন npm react-hook-form zod @hookform/resolvers @tanstack/react-query সংস্থাপন কৰক
জোড আঁচনি আৰম্ভ কৰোঁ Zod আঁচনিৰ পৰা, কাৰণ সাধাৰণতে তাতেই ফৰ্মৰ আকৃতি প্ৰতিষ্ঠা হয়। প্ৰথম দুটা পদক্ষেপৰ বাবে — ব্যক্তিগত বিৱৰণ আৰু অৰ্ডাৰ ইনপুটসমূহ — সকলো পোনপটীয়া: প্ৰয়োজনীয় ষ্ট্ৰিংসমূহ, নূন্যতমসমূহৰ সৈতে সংখ্যাসমূহ, আৰু এটা enum। চৰ্তযুক্ত নিয়মবোৰ প্ৰকাশ কৰিবলৈ চেষ্টা কৰিলে আকৰ্ষণীয় অংশটো আৰম্ভ হয়।
"zod" ৰ পৰা { z } আমদানি কৰক;
export const formSchema = z.object({ firstName: z.string().min(1, "প্ৰয়োজনীয়"), ইমেইল: z.string().email("অবৈধ ইমেইল"), মূল্য: z.number().min(0), পৰিমাণ: z.number().min(1), taxRate: z.number(), hasAccount: z.enum(["হয়", "নাই"]), ব্যৱহাৰকাৰীৰ নাম: z.string().ঐচ্ছিক(), পাছৱৰ্ড: z.string().ঐচ্ছিক(), সন্তুষ্টি: z.number().min(1).max(5), positiveFeedback: z.string().ঐচ্ছিক(), উন্নতিৰFeedback: z.string().ঐচ্ছিক(),}).superRefine((ডাটা, ctx) => { যদি (data.hasAccount === "হয়") { যদি (!data.username) { ctx.addIssue({ ক'ড: "স্বনিৰ্বাচিত", পথ: ["ব্যৱহাৰকাৰীৰ নাম"], বাৰ্তা: "প্ৰয়োজনীয়" });
if (data.satisfaction >= 4 && !data.positiveFeedback) { ctx.addIssue({ ক'ড: "স্বনিৰ্বাচিত", পথ: ["ধনাত্মক মতামত"], বাৰ্তা: "আপুনি যি ভাল পাইছে সেয়া অনুগ্ৰহ কৰি শ্বেয়াৰ কৰক" }); }
যদি (তথ্য.সন্তুষ্টি <= 2 && !ডাটা.উন্নতিৰ মতামত) { ctx.addIssue({ ক'ড: "স্বনিৰ্বাচিত", পথ:["improvementFeedback"], message: "অনুগ্ৰহ কৰি আমাক কি উন্নত কৰিব লাগে কওক" }); }});
ৰপ্তানিৰ ধৰণ FormData = z.infer
মন কৰক যে ব্যৱহাৰকাৰীৰ নাম আৰু পাছৱৰ্ডক ঐচ্ছিক() হিচাপে টাইপ কৰা হয় যদিও সিহঁত চৰ্তসাপেক্ষভাৱে প্ৰয়োজনীয় কাৰণ Zod ৰ টাইপ-স্তৰৰ আঁচনিয়ে বস্তুটোৰ আকৃতি বৰ্ণনা কৰে, ক্ষেত্ৰসমূহে কেতিয়া গুৰুত্বপূৰ্ণ হয় সেইটো নিয়ন্ত্ৰণ কৰা নিয়মসমূহ নহয়। চৰ্তযুক্ত প্ৰয়োজনীয়তা superRefine ৰ ভিতৰত থাকিব লাগিব, যি আকৃতি বৈধ হোৱাৰ পিছত চলে আৰু সম্পূৰ্ণ বস্তুটোৰ অভিগম আছে। সেই বিচ্ছেদ কোনো ত্ৰুটি নহয়; ইয়াৰ বাবে সঁজুলিটো ডিজাইন কৰা হৈছে: superRefine হৈছে য’ত ক্ৰছ-ফিল্ড লজিক যায় যেতিয়া ইয়াক আঁচনিৰ গঠনত প্ৰকাশ কৰিব নোৱাৰি। ইয়াত যিটো কথাও উল্লেখযোগ্য সেয়া হ’ল এই আঁচনিখনে কি প্ৰকাশ নকৰে। ইয়াত পৃষ্ঠাৰ কোনো ধাৰণা নাই, কোনটো ক্ষেত্ৰ কোনটো বিন্দুত দেখা যায় তাৰ কোনো ধাৰণা নাই আৰু নেভিগেচনৰ কোনো ধাৰণা নাই। সেই সকলোবোৰ আন ঠাইত থাকিব। ফৰ্ম উপাদান
import { useForm, useWatch } from "react-hook-form";import { zodResolver } from "@hookform/resolvers/zod";import { useMutation } from "@tanstack/react-query";import { useState, useMemo } from "react";import { formSchema, type FormData } from "./schema";
const STEPS = ["বিৱৰণ", "ক্ৰম", "একাউন্ট", "পৰ্যালোচনা"];
type OrderPayload = FormData & { উপমুঠ: সংখ্যা; কৰ: সংখ্যা; মুঠ: সংখ্যা };
ৰপ্তানি ফাংচন RHFMultiStepForm() { const [পদক্ষেপ, setStep] = useState(0);
const মিউটেচন = ব্যৱহাৰ মিউটেচন({ mutationFn: async (পেলোড: অৰ্ডাৰপেলোড) => { const res = অপেক্ষা কৰক fetch("/api/orders", { পদ্ধতি: "POST", headers: { "সামগ্ৰী-প্ৰকাৰ": "এপ্লিকেচন/json" }, শৰীৰ: JSON.stringify(পেলোড), }); if (!res.ok) throw new Error("জমা দিয়াত ব্যৰ্থ"); res.json() ঘূৰাই দিয়ক; }, });
const { পঞ্জীয়ন, নিয়ন্ত্ৰণ, handleSubmit, formState: { ভুল }, } = useForm
return (
);}ষষ্ঠ বিলুপ্তিৰ দ্বাৰা পেন জৰীপJS-03-RHF [forked] চাওক। ইয়াত যথেষ্ট কথাই ঘটি আছে, আৰু কথাবোৰ ক’ত শেষ হ’ল সেইটো লক্ষ্য কৰিবলৈ লেহেমীয়া কৰাটো যথেষ্ট৷
ব্যুৎপন্ন মানসমূহ — উপমুঠ, কৰ, মুঠ — useWatch আৰু useMemo ৰ যোগেদি উপাদানত গণনা কৰা হয় কাৰণ ইহঁত লাইভ ক্ষেত্ৰ মানসমূহৰ ওপৰত নিৰ্ভৰশীল আৰু ইয়াৰ বাবে অন্য কোনো প্ৰাকৃতিক স্থান নাই। ব্যৱহাৰকাৰীৰ নাম, গুপ্তশব্দ, positiveFeedback, আৰু improvementFeedback ৰ বাবে দৃশ্যমানতা নিয়মসমূহ JSX ত ইনলাইন চৰ্ত হিচাপে থাকে। ষ্টেপ-স্কিপিং লজিক — পৰ্যালোচনা পৃষ্ঠা কেৱল যেতিয়া মুঠ >= 100 দেখা দিয়ে — showSubmit চলক আৰু স্তৰ 3 ত ৰেণ্ডাৰ অৱস্থাত সন্নিৱিষ্ট কৰা হয়। নেভিগেচন নিজেই কেৱল এটা useState কাউণ্টাৰ যিটো আমি নিজেই বৃদ্ধি কৰিছো৷ React Query এ পুনৰ চেষ্টা, কেচিং, আৰু অবৈধকৰণ নিয়ন্ত্ৰণ কৰে। ফৰ্মটোৱে মাত্ৰ বৈধ তথ্যৰ সৈতে mutation.mutate কল কৰে।
এইবোৰৰ কোনোটোৱেই ভুল নহয়, নিজৰ বাবেই। এইটো এতিয়াও প্ৰচলিত React, আৰু উপাদানটো যথেষ্ট পৰিৱেশনশীল কাৰণ RHF এ কেনেকৈ পুনৰ ৰেণ্ডাৰ পৃথক কৰে। কিন্তু যদি আপুনি এইটো লিখা নাই কোনোবা এজনৰ হাতত তুলি দিয়ে আৰু তেওঁলোকক পৰ্যালোচনা পৃষ্ঠাটো কি চৰ্তত দেখা যায় সেই বিষয়ে বুজাবলৈ কয়, তেন্তে তেওঁলোকে showSubmit, স্তৰ ৩ ৰেণ্ডাৰ চৰ্ত, আৰু nav বুটাম লজিকৰ জৰিয়তে অনুসৰণ কৰিব লাগিব — তিনিটা পৃথক স্থান — এটা নিয়ম পুনৰ নিৰ্মাণ কৰিবলৈ যিটো এটা শাৰীত উল্লেখ কৰিব পৰা গ’লহেঁতেন। ফৰ্মখনে কাম কৰে, হয়, কিন্তু আচৰণটো আচলতে এটা ব্যৱস্থা হিচাপে পৰিদৰ্শনযোগ্য নহয়। ইয়াক মানসিকভাৱে ফাঁচী দিব লাগিব। তাতোকৈ ডাঙৰ কথাটো হ’ল ইয়াক সলনি কৰিবলৈ অভিযান্ত্ৰিক জড়িততাৰ প্ৰয়োজন। আনকি এটা সৰু টুইক, যেনে পৰ্যালোচনা পদক্ষেপ দেখুৱাৰ সময়ত সামঞ্জস্য কৰা, উপাদান সম্পাদনা কৰা, বৈধকৰণ আপডেইট কৰা, এটা টানি অনুৰোধ খোলা, পৰ্যালোচনাৰ বাবে অপেক্ষা কৰা, আৰু পুনৰায় মোতায়েন কৰা। ২য় খণ্ড: আঁচনি-চালিত (জৰীপJS) এতিয়া এটা আঁচনি ব্যৱহাৰ কৰি একেটা প্ৰবাহ নিৰ্মাণ কৰা যাওক। সংস্থাপন npm জৰীপ-কোৰ জৰীপ-প্ৰতিক্ৰিয়া-ui @tanstack/react-query সংস্থাপন কৰক
survey-coreMIT-লাইচেন্সযুক্ত প্লেটফৰ্ম-স্বাধীন ৰানটাইম ইঞ্জিন যিয়ে SurveyJS ৰ ফৰ্ম ৰেণ্ডাৰক শক্তি প্ৰদান কৰে — আমি ইয়াত গুৰুত্ব দিয়া অংশ। ই এটা JSON আঁচনি লয়, ইয়াৰ পৰা এটা অভ্যন্তৰীণ আৰ্হি নিৰ্মাণ কৰে, আৰু অন্যথা আপোনাৰ React উপাদানত থকা সকলো নিয়ন্ত্ৰণ কৰে: দৃশ্যমানতা অভিব্যক্তিসমূহ মূল্যায়ন কৰা, ব্যুৎপন্ন মানসমূহ গণনা কৰা, পৃষ্ঠাৰ অৱস্থা পৰিচালনা কৰা, বৈধকৰণ অনুসৰণ কৰা, আৰু কোনবোৰ পৃষ্ঠা প্ৰকৃততে দেখুওৱা হৈছিল সেই বিষয়ে “সম্পূৰ্ণ”ৰ অৰ্থ কি সেইটো সিদ্ধান্ত লোৱা।
survey-react-uiUI / ৰেণ্ডাৰ স্তৰ যি সেই আৰ্হিক React ৰ সৈতে সংযোগ কৰে। ই মূলতঃ এটা
একেলগে, সিহঁতে আপোনাক এটা সম্পূৰ্ণ কাৰ্য্যক্ষম, বহু-পৃষ্ঠা ফৰ্ম চলনসময় দিয়ে নিয়ন্ত্ৰণ প্ৰবাহৰ এটা শাৰী লিখা নোহোৱাকৈ। আঁচনি বিন্যাস নিজেই, আগতে কোৱাৰ দৰে, কেৱল এটা JSON — কোনো DSL বা কোনো মালিকানাধীন কোনো নাই। আপুনি ইয়াক ইনলাইন কৰিব পাৰে, এটা ফাইলৰ পৰা ইয়াক আমদানি কৰিব পাৰে, এটা API ৰ পৰা ইয়াক আনিব পাৰে, বা ইয়াক এটা ডাটাবেইচ স্তম্ভত সংৰক্ষণ কৰিব পাৰে আৰু ইয়াক চলনৰ সময়ত হাইড্ৰেট কৰিব পাৰে। একেটা ৰূপ, তথ্যৰ দৰে ইয়াত একেটা ফৰ্ম আছে, এইবাৰ এটা JSON বস্তু হিচাপে প্ৰকাশ কৰা হৈছে। আঁচনিয়ে সকলো সংজ্ঞায়িত কৰে: গঠন, বৈধকৰণ, দৃশ্যমানতা নিয়ম, ব্যুৎপন্ন গণনা, পৃষ্ঠা নেভিগেচন — আৰু ইয়াক এটা আৰ্হিলৈ দিয়ে যি ইয়াক চলনৰ সময়ত মূল্যায়ন কৰে। ইয়াত সেইটো সম্পূৰ্ণৰূপে কেনেকুৱা দেখা যায়:
export const surveySchema = { title: "ক্ৰম প্ৰবাহ", showProgressBar: "শীৰ্ষ", পৃষ্ঠা: [ { নাম: "বিৱৰণ", উপাদান: [ { ধৰণ: "পাঠ", নাম: "প্ৰথম নাম", isRequired: true }, { ধৰণ: "পাঠ", নাম: "ইমেইল", inputType: "ইমেইল", isRequired: সত্য, বৈধকৰ্তা: [{ ধৰণ: "ইমেইল", লিখনী: "অবৈধ ইমেইল" }] } ] }, { নাম: "ক্ৰম", উপাদানসমূহ: [ { ধৰণ: "পাঠ্য", নাম: "মূল্য", inputType: "সংখ্যা", অবিকল্পিতমূল্য: 0 }, { ধৰণ: "পাঠ", নাম: "পৰিমাণ", inputType: "সংখ্যা", অবিকল্পিতমূল্য: 1 }, { ধৰণ: "ড্ৰপডাউন",নাম: "taxRate", অবিকল্পিতমূল্য: 0.1, পছন্দসমূহ: [ { মান: 0.05, লিখনী: "5%" }, { মান: 0.1, লিখনী: "10%" }, { মান: 0.15, লিখনী: "15%" } ] }, { ধৰণ: "প্ৰকাশ", নাম: "উপমুঠ", অভিব্যক্তি: "{মূল্য} {পৰিমাণ}" }, { ধৰণ: "এক্সপ্ৰেচন", নাম: "কৰ", এক্সপ্ৰেচন: "{subtotal} {taxRate}" }, { ধৰণ: "expression", নাম: "total", এক্সপ্ৰেচন: "{subtotal} + {tax}" } ] }, { নাম: "একাউন্ট", উপাদান: [ { ধৰণ: "ৰেডিঅ'গ্ৰুপ", নাম: "hasAccount", পছন্দ: ["হয়", "নাই"] } , { ধৰণ: "টেক্সট", নাম: "ব্যৱহাৰকাৰীৰ নাম", visibleIf: "{hasAccount} = 'হয়'", isRequired: true }, { ধৰণ: "পাঠ্য", নাম: "পাছৱৰ্ড", inputType: "পাছৱৰ্ড", visibleIf: "{hasAccount} = 'হয়'", isRequired: true, validators: [{ type: "text", minLength: 6, text: "Min 6 characters" }] }, { ধৰণ: "ৰেটিং", নাম: "সন্তুষ্টি", rateMin: 1, rateMax: 5 }, { ধৰণ: "মন্তব্য", নাম: "ধনাত্মক মতামত", visibleIf: "{সন্তুষ্টি} >= 4" }, { ধৰণ: "মন্তব্য", নাম: "উন্নতিৰ প্ৰতিক্ৰিয়া", visibleIf: "{সন্তুষ্টি} <= 2" } ] }, { নাম: "পৰ্যালোচনা", visibleIf: "{মুঠ} >= ১০০", উপাদানসমূহ: [] } ]};
ইয়াক ক্ষন্তেক সময়ৰ বাবে RHF সংস্কৰণৰ সৈতে তুলনা কৰক।
চৰ্তসাপেক্ষে ব্যৱহাৰকাৰীৰ নাম আৰু পাছৱৰ্ডৰ প্ৰয়োজন হোৱা superRefine ব্লক নাইকিয়া হৈ গৈছে। visibleIf: "{hasAccount} = 'Yes'" isRequired ৰ সৈতে সংযুক্ত: true এ দুয়োটা উদ্বেগ একেলগে নিয়ন্ত্ৰণ কৰে, ক্ষেত্ৰত নিজেই, য'ত আপুনি সিহতক বিচাৰি পাব বুলি আশা কৰিব। useWatch + useMemo শৃংখল যি উপমুঠ, কৰ, আৰু মুঠ গণনা কৰিছিল তিনিটা এক্সপ্ৰেচন ক্ষেত্ৰৰ দ্বাৰা সলনি কৰা হয় যি ইটোৱে সিটোক নামেৰে উল্লেখ কৰে। পৰ্যালোচনা পৃষ্ঠাৰ অৱস্থা, যি RHF সংস্কৰণত কেৱল showSubmit, স্তৰ ৩ ৰেণ্ডাৰ শাখাৰ যোগেদি অনুসৰণ কৰি পুনৰ্গঠনযোগ্য আছিল। আৰু শেষত, nav বুটাম লজিকটো হৈছে পৃষ্ঠা বস্তুটোৰ এটা visibleIf বৈশিষ্ট্য।
একেটা যুক্তি আছে। মাত্ৰ আঁচনিখনে ইয়াক উপাদানটোৰ মাজেৰে বিয়পি পৰাতকৈ, পৃথকে পৃথকে দেখা পোৱা ঠাইত থাকিবলৈ এটা ঠাই দিয়ে। লগতে, মন কৰিব যে আঁচনিখনে উপমুঠ, কৰ, আৰু মুঠৰ বাবে ধৰণ ব্যৱহাৰ কৰে: 'এক্সপ্ৰেচন'। এক্সপ্ৰেচন কেৱল পঢ়িব পৰা আৰু মূলতঃ গণনা কৰা মানসমূহ প্ৰদৰ্শন কৰিবলৈ ব্যৱহাৰ কৰা হয়। SurveyJS এ স্থিতিশীল বিষয়বস্তুৰ বাবে ধৰণ: 'html'ও সমৰ্থন কৰে, কিন্তু গণনা কৰা মানসমূহৰ বাবে, অভিব্যক্তি সঠিক পছন্দ। এতিয়া React পক্ষৰ বাবে। ৰেণ্ডাৰ আৰু জমা দিয়া অতি সহজ। আপোনাৰ API লৈ onComplete একে ধৰণেৰে তাঁৰ কৰক — useMutation বা plain fetch ৰ যোগেদি:
import { useState, useEffect, useRef } from "react";import { useMutation } from "@tanstack/react-query";import { Model } from "survey-core";import { জৰীপ } "জৰীপ-প্ৰতিক্ৰিয়া-ui" ৰ পৰা;আমদানি "জৰীপ-কোৰ/জৰীপ-কোৰ.css";
ৰপ্তানি ফাংচন SurveyForm() { const [মডেল] = useState(() => নতুন মডেল(জৰীপ আঁচনি));
const মিউটেচন = ব্যৱহাৰ মিউটেচন({ মিউটেচনFn: async (তথ্য) => { const res = অপেক্ষা কৰক fetch("/api/orders", { পদ্ধতি: "POST", headers: { "সামগ্ৰী-প্ৰকাৰ": "এপ্লিকেচন/json" }, শৰীৰ: JSON.stringify(তথ্য), }); if (!res.ok) throw new Error("জমা দিয়াত ব্যৰ্থ"); res.json() ঘূৰাই দিয়ক; }, });
const মিউটেচনRef = useRef (মিউটেচন); মিউটেচনRef.current = মিউটেচন; useEffect(() => { const হেণ্ডলাৰ = (প্ৰেৰক) => মিউটেচনRef.current.mutate(প্ৰেৰক.ডাটা); // ref এ প্ৰতিটো ৰেণ্ডাৰত হেণ্ডলাৰক পুনৰ পঞ্জীয়ন কৰাটো এৰাই চলিব (মিউটেচন বস্তুৰ পৰিচয় সলনি হয়)
return ( <> <জৰীপ মডেল={মডেল} /> {মিউটেচন.isError &&
পেন জৰীপJS-03-জৰীপJS [forked] sixthextinction দ্বাৰা চাওক।
onComplete জুই জ্বলায় যেতিয়া ব্যৱহাৰকাৰীয়ে শেষ দৃশ্যমান পৃষ্ঠাৰ শেষত উপনীত হয়। গতিকে যদি মুঠ কেতিয়াও ১০০ অতিক্ৰম নকৰে আৰু পৰ্যালোচনা পৃষ্ঠাটো এৰি দিয়া হয়, তথাপিও ই সঠিকভাৱে গুলিয়াই দিয়ে কাৰণ SurveyJS এ “শেষ পৃষ্ঠা”ৰ অৰ্থ কি সেইটো নিৰ্ণয় কৰাৰ আগতে দৃশ্যমানতা মূল্যায়ন কৰে। তাৰ পিছত, sender.data এ গণনা কৰা মানসমূহৰ সৈতে সকলো উত্তৰ (উপমুঠ, কৰ, মুঠ) প্ৰথম-শ্ৰেণীৰ ক্ষেত্ৰ হিচাপে ধাৰণ কৰে, গতিকে API পেলোড RHF সংস্কৰণে onSubmit ত হস্তচালিতভাৱে একত্ৰিত কৰা সৈতে একে। দ্য...mutationRef প্যাটাৰ্ন একেই যিটো আপুনি যিকোনো ঠাইতে পাব যিটো প্ৰতিটো ৰেণ্ডাৰত সলনি হোৱা এটা মানৰ ওপৰত এটা সুস্থিৰ ইভেন্ট হেণ্ডলাৰৰ প্ৰয়োজন হয় — ইয়াৰ বিষয়ে SurveyJS-নিৰ্দিষ্ট একো নাই।
React উপাদানত আৰু কোনো ব্যৱসায়িক যুক্তি একেবাৰেই নাই। ইয়াত কোনো useWatch নাই, কোনো চৰ্তযুক্ত JSX নাই, কোনো ষ্টেপ কাউণ্টাৰ নাই, কোনো useMemo চেইন নাই, কোনো superRefine নাই৷ React এ প্ৰকৃততে ভাল কামটো কৰি আছে: এটা উপাদান ৰেণ্ডাৰ কৰা আৰু ইয়াক এটা API কললৈ তাঁৰ সংযোগ কৰা। ৰিএক্টৰ পৰা কি ওলাই আহিল?
চিন্তা আৰ এইচ এফ ষ্টেক জৰীপJS দৃশ্যমানতা JSX শাখাসমূহ visibleIf ব্যুৎপন্ন মানসমূহ useWatch / useMemo অভিব্যক্তি ক্ৰছ-ফিল্ডৰ নিয়ম superRefine ৰ দ্বাৰা আঁচনিৰ চৰ্তসমূহ নেভিগেচন ষ্টেপ ষ্টেট পৃষ্ঠা দৃশ্যমানIf নিয়মৰ স্থান ফাইলসমূহৰ মাজেৰে বিতৰণ কৰা হৈছে আঁচনিখনত কেন্দ্ৰীভূত কৰা হৈছে
React ত যি থাকে সেয়া হ'ল লেআউট, ষ্টাইলিং, জমা তাঁৰ, আৰু এপ সংহতি, অৰ্থাৎ, React প্ৰকৃততে ডিজাইন কৰা বস্তুবোৰৰ বাবে। বাকী সকলো আঁচনিলৈ স্থানান্তৰ কৰা হৈছে, আৰু যিহেতু আঁচনিখন কেৱল এটা JSON বস্তু, ইয়াক এটা ডাটাবেইচত সংৰক্ষণ কৰিব পাৰি, আপোনাৰ এপ্লিকেচন ক'ডৰ পৰা স্বতন্ত্ৰভাৱে সংস্কৰণ কৰিব পাৰি, বা এটা মোতায়েনৰ প্ৰয়োজন নোহোৱাকৈ অভ্যন্তৰীণ সঁজুলিৰ যোগেদি সম্পাদনা কৰিব পাৰি। এজন প্ৰডাক্ট মেনেজাৰ যিয়ে পৰ্যালোচনা পৃষ্ঠা ট্ৰিগাৰ কৰা থ্ৰেছহ'ল্ড সলনি কৰিব লাগে তেওঁ উপাদানটো স্পৰ্শ নকৰাকৈয়ে সেইটো কৰিব পাৰে। য’ত ফৰ্মৰ আচৰণ সঘনাই বিকশিত হয় আৰু সদায় অভিযন্তাৰ দ্বাৰা পৰিচালিত নহয়, তেনে দলৰ বাবে সেইটো এটা অৰ্থপূৰ্ণ কাৰ্য্যকৰী পাৰ্থক্য। প্ৰতিটো পদ্ধতি কেতিয়া ব্যৱহাৰ কৰিব লাগে? মোৰ বাবে কাম কৰা এটা ভাল নিয়ম আছে: কল্পনা কৰক যে ফৰ্মখন সম্পূৰ্ণৰূপে মচি পেলোৱা হৈছে। আপুনি কি হেৰুৱাব?
যদি ই পৰ্দাসমূহ, আপুনি উপাদান-চালিত প্ৰপত্ৰ বিচাৰে। যদি ই ব্যৱসায়িক যুক্তি, যেনে থ্ৰেছহ’ল্ড, শাখা নিয়ম, আৰু চৰ্তযুক্ত প্ৰয়োজনীয়তা যিয়ে প্ৰকৃত সিদ্ধান্তসমূহ এনকোড কৰে, আপুনি এটা আঁচনি ইঞ্জিন বিচাৰে৷
একেদৰে, যদি আপোনাৰ পথত অহা পৰিবৰ্তনসমূহ বেছিভাগেই লেবেল, ক্ষেত্ৰ, আৰু পৰিকল্পনাৰ বিষয়ে হয়, RHF এ আপোনাক ভালদৰে সেৱা আগবঢ়াব। যদি সেইবোৰ চৰ্ত, ফলাফল আৰু নিয়মৰ বিষয়ে হয় যিবোৰ আপোনাৰ অপ্ছ বা আইনী দলে টিকট দাখিল নকৰাকৈ মঙলবাৰে বিয়লি সামঞ্জস্য কৰিব লাগিব, তেন্তে SurveyJS ৰ সৈতে আঁচনি মডেলটো অধিক সৎ ফিট৷ এই দুটা পদ্ধতি আচলতে ইটোৱে সিটোৰ লগত প্ৰতিযোগিতাত নহয়। ইহঁতে বিভিন্ন শ্ৰেণীৰ সমস্যাৰ সমাধান কৰে, আৰু এৰাই চলাৰ যোগ্য ভুলটো হ’ল বিমূৰ্ততাক যুক্তিৰ ওজনৰ সৈতে মিল নথকা — এটা নিয়ম ব্যৱস্থাক এটা উপাদানৰ দৰে গণ্য কৰা কাৰণ সেইটোৱেই চিনাকি সঁজুলি, বা এটা নীতিৰ ইঞ্জিনৰ ওচৰলৈ হাত আগবঢ়োৱা কাৰণ এটা ফৰ্ম তিনিটা পদক্ষেপলৈ বৃদ্ধি পাইছিল আৰু এটা চৰ্তযুক্ত ক্ষেত্ৰ অধিগ্ৰহণ কৰিছিল। আমি ইয়াত নিৰ্মাণ কৰা ফৰ্মখন ইচ্ছাকৃতভাৱে সীমাৰ ওচৰত বহি আছে, পাৰ্থক্যটো উন্মোচন কৰিব পৰাকৈ জটিল কিন্তু ইমান চৰম নহয় যে তুলনাটো ৰিগ কৰা যেন লাগে। আপোনাৰ ক'ডবেছত অসহজ হৈ পৰা বেছিভাগ প্ৰকৃত ফৰ্ম সম্ভৱতঃ সেই একে সীমাৰ ওচৰত বহি থাকে, আৰু প্ৰশ্নটো সাধাৰণতে কেৱল কোনোবাই প্ৰকৃততে কি নাম দিছে নেকি। React Hook Form + Zod ব্যৱহাৰ কৰক যেতিয়া:
প্ৰপত্ৰসমূহ CRUD-মুখী; যুক্তি অগভীৰ আৰু UI-চালিত; অভিযন্তাসকলে সকলো আচৰণৰ মালিক; বেকএণ্ড সত্যৰ উৎস হৈয়েই আছে।
SurveyJS ব্যৱহাৰ কৰক যেতিয়া:
প্ৰপত্ৰসমূহে ব্যৱসায়িক সিদ্ধান্তসমূহ এনকোড কৰে; নিয়মসমূহ UI ৰ পৰা স্বাধীনভাৱে বিকশিত হয়; যুক্তি দৃশ্যমান, অডিটেবল, বা সংস্কৰণযুক্ত হ'ব লাগিব; অ-অভিযন্তাসকলে আচৰণক প্ৰভাৱিত কৰে; একেটা ফৰ্ম একাধিক ফ্ৰন্টএণ্ডৰ মাজেৰে চলিব লাগিব।