یہ مضمون سروے جے ایس کے زیر اہتمام ہے۔ ایک ذہنی ماڈل ہے جو زیادہ تر React ڈویلپرز اس پر کبھی بھی اونچی آواز میں بات کیے بغیر شیئر کرتے ہیں۔ اس فارم کو ہمیشہ اجزاء سمجھا جاتا ہے۔ اس کا مطلب ہے اسٹیک جیسے:
مقامی ریاست کے لیے ری ایکٹ ہک فارم (کم سے کم ری رینڈرز، ایرگونومک فیلڈ رجسٹریشن، لازمی تعامل)۔ توثیق کے لیے زوڈ (ان پٹ درستگی، باؤنڈری کی توثیق، ٹائپ سیف پارسنگ)۔ بیک اینڈ کے لیے ردعمل کا سوال: جمع کرانے، دوبارہ کوششیں، کیشنگ، سرور کی مطابقت پذیری، اور اسی طرح کی۔
اور فارموں کی اکثریت کے لیے — آپ کی لاگ ان اسکرینز، آپ کی ترتیبات کے صفحات، آپ کے CRUD ماڈلز — یہ واقعی اچھی طرح کام کرتا ہے۔ ہر ٹکڑا اپنا کام کرتا ہے، وہ صاف ستھرا کمپوز کرتے ہیں، اور آپ اپنی ایپلی کیشن کے ان حصوں کی طرف جا سکتے ہیں جو آپ کی پروڈکٹ کو حقیقت میں مختلف کرتے ہیں۔ لیکن ہر ایک بار تھوڑی دیر میں، ایک فارم چیزوں کو جمع کرنا شروع کر دیتا ہے جیسے مرئیت کے اصول جو پہلے کے جوابات پر منحصر ہوتے ہیں، یا اخذ کردہ اقدار جو تین شعبوں سے گزرتی ہیں۔ ہو سکتا ہے کہ پورے صفحات کو چھوڑ دیا جائے یا چلنے والے کل کی بنیاد پر دکھایا جائے۔ آپ یوز واچ اور ان لائن برانچ کے ساتھ پہلی مشروط کو ہینڈل کرتے ہیں، جو کہ ٹھیک ہے۔ پھر ایک اور۔ پھر آپ کراس فیلڈ رولز کو انکوڈ کرنے کے لیے سپر ریفائن تک پہنچ رہے ہیں جن کا آپ کا Zod اسکیما عام انداز میں اظہار نہیں کر سکتا۔ پھر، مرحلہ وار نیویگیشن کاروباری منطق کو لیک کرنا شروع کر دیتی ہے۔ کسی وقت، آپ دیکھتے ہیں کہ آپ نے کیا بنایا ہے اور احساس ہوتا ہے کہ فارم واقعی UI نہیں ہے۔ یہ فیصلہ کرنے کا زیادہ عمل ہے، اور جزو کا درخت وہیں ہے جہاں آپ نے اسے ذخیرہ کیا تھا۔ یہ وہ جگہ ہے جہاں میرے خیال میں React میں شکلوں کا ذہنی ماڈل ٹوٹ جاتا ہے، اور یہ واقعی کسی کی غلطی نہیں ہے۔ RHF + Zod اسٹیک اس کے لیے بہترین ہے جس کے لیے اسے ڈیزائن کیا گیا تھا۔ مسئلہ یہ ہے کہ ہم اسے اس نقطہ سے گزرتے رہتے ہیں جہاں اس کے تجریدات مسئلے سے میل کھاتے ہیں کیونکہ متبادل کو مکمل طور پر شکلوں کے بارے میں سوچنے کا ایک مختلف طریقہ درکار ہوتا ہے۔ یہ مضمون اس متبادل کے بارے میں ہے۔ اس کو دکھانے کے لیے، ہم دو بار بالکل وہی ملٹی سٹیپ فارم بنائیں گے:
React Hook Form + Zod کے ساتھ React Query جمع کرانے کے لیے، SurveyJS کے ساتھ، جو ایک فارم کو ڈیٹا کے طور پر لیتا ہے — ایک سادہ JSON اسکیما — بجائے کہ ایک جزو درخت۔
وہی تقاضے، وہی مشروط منطق، آخر میں وہی API کال۔ پھر ہم بالکل نقشہ بنائیں گے کہ کیا منتقل ہوا اور کیا ٹھہرا، اور یہ فیصلہ کرنے کے لیے ایک عملی طریقہ ترتیب دیں گے کہ آپ کو کون سا ماڈل استعمال کرنا چاہیے، اور کب۔ فارم جو ہم بنا رہے ہیں:
یہ فارم 4 قدمی بہاؤ کا استعمال کرے گا: مرحلہ 1: تفصیلات
پہلا نام (ضروری) ای میل (ضروری، درست فارمیٹ)۔
مرحلہ 2: آرڈر کریں۔
یونٹ کی قیمت، مقدار، ٹیکس کی شرح، ماخوذ: ذیلی کل، ٹیکس، کل
مرحلہ 3: اکاؤنٹ اور تاثرات
کیا آپ کا اکاؤنٹ ہے؟ (ہاں/نہیں) اگر ہاں → صارف نام + پاس ورڈ، دونوں کی ضرورت ہے۔ اگر نہیں → ای میل پہلے ہی مرحلہ 1 میں جمع ہو چکی ہے۔
اطمینان کی درجہ بندی (1–5) اگر ≥ 4 → پوچھے "آپ کو کیا پسند ہے؟" اگر ≤ 2 → پوچھے "ہم کیا بہتر کر سکتے ہیں؟"
مرحلہ 4: جائزہ لیں۔
صرف تب ظاہر ہوتا ہے جب کل >= 100 ہو۔ حتمی جمع کروانا۔
یہ انتہا نہیں ہے۔ لیکن یہ تعمیراتی اختلافات کو بے نقاب کرنے کے لئے کافی ہے۔ حصہ 1: اجزاء سے چلنے والا (ری ایکٹ ہک فارم + زوڈ) تنصیب npm install react-hook-form zod @hookform/resolvers @tanstack/react-query
زود سکیما آئیے Zod اسکیما کے ساتھ شروع کریں، کیونکہ عام طور پر یہ وہ جگہ ہے جہاں فارم کی شکل قائم ہوتی ہے۔ پہلے دو مراحل کے لیے — ذاتی تفصیلات اور آرڈر کی معلومات — سب کچھ سیدھا ہے: مطلوبہ تار، کم از کم نمبر، اور ایک اینوم۔ دلچسپ حصہ اس وقت شروع ہوتا ہے جب آپ مشروط قواعد کو بیان کرنے کی کوشش کرتے ہیں۔
"zod" سے { z } درآمد کریں؛
ایکسپورٹ const formSchema = z.object({ firstName: z.string().min(1, "Required"), email: z.string().email("غلط ای میل"), قیمت: z.number().min(0), مقدار: z.number().min(1), tax Rate: z.number().min(1), tax Rate: z.number(", . "No"])، صارف کا نام: z.string().optional(), پاس ورڈ: z.string().optional(), satisfaction: z.number().min(1).max(5), positive Feedback: z.string().optional(), improvement Feedback: z.string().optional(ef), ine (fine) =(xta))super (data.hasAccount === "Yes") { if (!data.username) { ctx.addIssue({ code: "custom", path: ["username"], message: "Required" } }; ["پاس ورڈ"]، پیغام: "کم سے کم 6 حروف" })؛
if (data.satisfaction >= 4 && !data.positiveFeedback) { ctx.addIssue({ code: "custom", path: ["positiveFeedback"], پیغام: "براہ کرم شیئر کریں جو آپ کو پسند آیا" }); }
اگر (data.satisfaction <= 2 && !data.improvementFeedback) { ctx.addIssue({ کوڈ: "کسٹم"، راستہ:["improvementFeedback"], پیغام: "براہ کرم ہمیں بتائیں کہ کیا بہتر کرنا ہے" }); }});
برآمد کی قسم FormData = z.infer
نوٹ کریں کہ صارف نام اور پاس ورڈ بطور اختیاری () ٹائپ کیے گئے ہیں حالانکہ وہ مشروط طور پر درکار ہیں کیونکہ Zod کا ٹائپ لیول سکیما آبجیکٹ کی شکل کو بیان کرتا ہے، نہ کہ اصولوں کی جب فیلڈز کی اہمیت ہو۔ مشروط ضرورت کو سپر ریفائن کے اندر رہنا پڑتا ہے، جو شکل کی توثیق کے بعد چلتا ہے اور اسے مکمل آبجیکٹ تک رسائی حاصل ہوتی ہے۔ وہ جدائی کوئی عیب نہیں ہے۔ یہ صرف وہی ہے جس کے لیے ٹول ڈیزائن کیا گیا ہے: سپر ریفائن وہ جگہ ہے جہاں کراس فیلڈ منطق اس وقت جاتی ہے جب اسکیما ڈھانچے میں ہی اس کا اظہار نہیں کیا جاسکتا ہے۔ یہاں جو چیز بھی قابل ذکر ہے وہ یہ ہے کہ اس اسکیما کا اظہار نہیں کیا گیا ہے۔ اس میں صفحات کا کوئی تصور نہیں ہے، اس کا کوئی تصور نہیں ہے کہ کون سے فیلڈز کس مقام پر نظر آتے ہیں، اور نہ ہی نیویگیشن کا کوئی تصور۔ یہ سب کہیں اور رہیں گے۔ فارم کا جزو
"react-hook-form" سے { useForm, useWatch } درآمد کریں؛ "@hookform/resolvers/zod" سے { zodResolver } درآمد کریں؛ "@tanstack/react-query" سے { useMutation } درآمد کریں؛ "react" سے { useState, useMemo } درآمد کریں؛ "react" سے درآمد کریں؛ "maata" فارم سے درآمد کریں؛ "/Dma" فارم سے درآمد کریں۔
const STEPS = ["تفصیلات"، "آرڈر"، "اکاؤنٹ"، "جائزہ"]؛
قسم OrderPayload = FormData & { ذیلی ٹوٹل: نمبر؛ ٹیکس: نمبر؛ کل: نمبر }؛
ایکسپورٹ فنکشن RHFMultiStepForm() { const [step, setStep] = useState(0)؛
const mutation = useMutation({ mutationFn: async (payload: OrderPayload) => { const res = انتظار کریں بازیافت ("/api/orders"، { طریقہ: "پوسٹ"، ہیڈر: { "مواد کی قسم": "درخواست/json" }، باڈی: JSON.stringify(payload)، }); اگر (!res.ok) نئی خرابی پھینک دیں("جمع کرانے میں ناکام")؛ واپسی res.json(); }، });
const {رجسٹر، کنٹرول، ہینڈل جمع کروائیں، فارم اسٹیٹ: { errors }، } = useForm
واپس کریں (
);}Pen SurveyJS-03-RHF دیکھیں یہاں بہت کچھ ہو رہا ہے، اور یہ دیکھنا ضروری ہے کہ چیزیں کہاں ختم ہوئیں۔
اخذ کردہ اقدار — ذیلی ٹوٹل، ٹیکس، کُل — کو اجزاء میں UseWatch اور useMemo کے ذریعے شمار کیا جاتا ہے کیونکہ وہ لائیو فیلڈ ویلیوز پر منحصر ہیں اور ان کے لیے کوئی دوسری قدرتی جگہ نہیں ہے۔ یوزر نیم، پاس ورڈ، مثبت فیڈ بیک، اور بہتری فیڈ بیک کے لیے مرئیت کے اصول JSX میں ان لائن مشروط کے طور پر رہتے ہیں۔ قدم چھوڑنے کی منطق — جائزے کا صفحہ صرف اس وقت ظاہر ہوتا ہے جب کل >= 100 — شو سبمٹ متغیر اور مرحلہ 3 پر رینڈر کی حالت میں سرایت کرتا ہے۔ نیویگیشن بذات خود صرف یوز اسٹیٹ کاؤنٹر ہے جسے ہم دستی طور پر بڑھا رہے ہیں۔ React Query دوبارہ کوششوں، کیشنگ، اور باطل کو ہینڈل کرتا ہے۔ فارم صرف تصدیق شدہ ڈیٹا کے ساتھ mutation.mutate کو کال کرتا ہے۔
اس میں سے کوئی بھی غلط نہیں ہے۔ یہ اب بھی محاوراتی ردعمل ہے، اور جزو کافی پرفارمنس ہے جس کی بدولت RHF دوبارہ رینڈر کو الگ کرتا ہے۔ لیکن اگر آپ اسے کسی ایسے شخص کے حوالے کرنا چاہتے تھے جس نے اسے نہیں لکھا تھا اور ان سے یہ بتانے کے لیے کہتا ہے کہ نظرثانی کا صفحہ کن حالات میں ظاہر ہوتا ہے، تو انہیں showSubmit، مرحلہ 3 رینڈر کنڈیشن، اور nav بٹن منطق کے ذریعے ٹریس کرنا پڑے گا — تین الگ الگ مقامات — ایک اصول کی تشکیل نو کے لیے جسے ایک لائن میں بیان کیا جا سکتا تھا۔ فارم کام کرتا ہے، ہاں، لیکن طرز عمل ایک نظام کے طور پر واقعی قابل معائنہ نہیں ہے۔ اسے ذہنی طور پر انجام دینا ہوگا۔ زیادہ اہم بات یہ ہے کہ اسے تبدیل کرنے کے لیے انجینئرنگ کی شمولیت کی ضرورت ہے۔ یہاں تک کہ ایک چھوٹی سی موافقت، جیسے کہ جائزے کا مرحلہ ظاہر ہونے پر ایڈجسٹ کرنا، کا مطلب ہے جزو میں ترمیم کرنا، توثیق کو اپ ڈیٹ کرنا، پل کی درخواست کھولنا، نظرثانی کا انتظار کرنا، اور دوبارہ تعینات کرنا۔ حصہ 2: سکیما پر مبنی (سروے جے ایس) اب آئیے ایک اسکیما کا استعمال کرتے ہوئے ایک ہی بہاؤ بنائیں۔ تنصیب npm install survey-core survey-react-ui @tanstack/react-query
سروے کور ایم آئی ٹی لائسنس یافتہ پلیٹ فارم سے آزاد رن ٹائم انجن جو SurveyJS کے فارم رینڈرنگ کو طاقت دیتا ہے — وہ حصہ جس کا ہمیں یہاں خیال ہے۔ یہ ایک JSON اسکیما لیتا ہے، اس سے ایک اندرونی ماڈل بناتا ہے، اور ہر وہ چیز سنبھالتا ہے جو بصورت دیگر آپ کے React جز میں زندہ رہے گا: مرئیت کے تاثرات کا اندازہ لگانا، اخذ کردہ اقدار کو کمپیوٹنگ کرنا، صفحہ کی حالت کا نظم کرنا، توثیق کا پتہ لگانا، اور یہ فیصلہ کرنا کہ "مکمل" کا کیا مطلب ہے یہ بتاتے ہوئے کہ اصل میں کون سے صفحات دکھائے گئے تھے۔
survey-react-uiThe UI / رینڈرنگ پرت جو اس ماڈل کو React سے جوڑتی ہے۔ یہ بنیادی طور پر ایک
ایک ساتھ مل کر، وہ آپ کو کنٹرول فلو کی ایک لائن لکھے بغیر مکمل طور پر فعال، ملٹی پیج فارم کا رن ٹائم دیتے ہیں۔ اسکیما فارمیٹ بذات خود ہے، جیسا کہ پہلے کہا گیا ہے، صرف ایک JSON — کوئی DSL یا کچھ بھی ملکیتی نہیں۔ آپ اسے ان لائن کر سکتے ہیں، اسے فائل سے درآمد کر سکتے ہیں، اسے API سے بازیافت کر سکتے ہیں، یا اسے ڈیٹا بیس کالم میں محفوظ کر سکتے ہیں اور رن ٹائم پر اسے ہائیڈریٹ کر سکتے ہیں۔ وہی فارم، جیسا کہ ڈیٹا یہاں وہی شکل ہے، اس بار JSON آبجیکٹ کے طور پر ظاہر کیا گیا ہے۔ اسکیما ہر چیز کی وضاحت کرتا ہے: ساخت، توثیق، مرئیت کے اصول، اخذ کردہ حسابات، صفحہ نیویگیشن — اور اسے ایک ایسے ماڈل کے حوالے کرتا ہے جو رن ٹائم کے وقت اس کا جائزہ لیتا ہے۔ یہاں یہ ہے کہ یہ مکمل طور پر کیا لگتا ہے:
export const surveySchema = { عنوان: "آرڈر فلو"، شو پروگریس بار: "اوپر"، صفحات: [ { نام: "تفصیلات"، عناصر: [ { قسم: "متن"، نام: "پہلا نام"، isRequired: true }، { type: "text"، name: "email"، inputType: "email"، isRequired: "True"، "email type:" }] } ] }، { نام: "آرڈر"، عناصر: [ { قسم: "ٹیکسٹ"، نام: "قیمت"، ان پٹ ٹائپ: "نمبر"، ڈیفالٹ ویلیو: 0 }، { ٹائپ: "ٹیکسٹ"، نام: "مقدار"، ان پٹ ٹائپ: "نمبر"، ڈیفالٹ ویلیو: 1 }، { ٹائپ: "ڈراپ ڈاؤن"،نام: "ٹیکس ریٹ"، ڈیفالٹ ویلیو: 0.1، انتخاب: [ { ویلیو: 0.05، ٹیکسٹ: "5%" }، { ویلیو: 0.1، ٹیکسٹ: "10%" }، { ویلیو: 0.15، ٹیکسٹ: "15%" } ] }، { ٹائپ: "اظہار"، نام: "subto}}، expression: "subto}}" قسم: "اظہار"، نام: "ٹیکس"، اظہار: "{subtotal} {taxRate}" }، { type: "expression", name: "total", expression: "{subtotal} + {tax}" } ] }, { name: "account"، عناصر: [ { type: "radiogroup"، name: "hasoAc}"، "hasoAc}"، [{type: "radiogroup", name: "hasoAc}" type: "text", name: "username", visibleIf: "{hasAccount} = 'Yes'", isRequired: true }, { type: "text", name: "password", inputType: "password", visibleIf: "{hasAccount} = 'Yes'", isRequired: true: 6, text, valid, type: "کم سے کم 6 حروف" }] }، { قسم: "درجہ بندی"، نام: "اطمینان"، شرح کم سے کم: 1، شرح میکس: 5 }، { قسم: "تبصرہ"، نام: "مثبت تاثرات"، visibleIf: "{ satisfaction} >= 4" }، { type: "comment}، name: "fvisible: "imfaction}" <= 2" } ] }، { نام: "جائزہ"، visibleIf: "{total} >= 100"، عناصر: [] } ]}؛
ایک لمحے کے لیے اس کا RHF ورژن سے موازنہ کریں۔
سپر ریفائن بلاک جو مشروط طور پر مطلوبہ صارف نام اور پاس ورڈ ختم ہو گیا ہے۔ visibleIf: "{hasAccount} = 'Yes'" isRequired کے ساتھ مل کر: true دونوں خدشات کو ایک ساتھ ہینڈل کرتا ہے، فیلڈ میں ہی، جہاں آپ انہیں تلاش کرنے کی توقع کریں گے۔ UseWatch + useMemo سلسلہ جو کہ ذیلی ٹوٹل، ٹیکس، اور ٹوٹل کا حساب لگاتا ہے، کو تین ایکسپریشن فیلڈز سے بدل دیا جاتا ہے جو ایک دوسرے کو نام سے حوالہ دیتے ہیں۔ جائزہ صفحہ کی حالت، جو کہ RHF ورژن میں صرف showSubmit، مرحلہ 3 رینڈر برانچ کے ذریعے ٹریس کر کے قابلِ تعمیر تھی۔ اور آخر میں، nav بٹن کی منطق ایک واحد visibleIf پراپرٹی ہے جو صفحہ آبجیکٹ پر ہے۔
وہاں بھی وہی منطق ہے۔ یہ صرف اتنا ہے کہ اسکیما اسے رہنے کے لئے ایک جگہ فراہم کرتا ہے جہاں یہ الگ تھلگ نظر آتا ہے، بجائے اس کے کہ وہ پورے جزو میں پھیل جائے۔ نیز، یہ بھی نوٹ کریں کہ اسکیما قسم کا استعمال کرتا ہے: ذیلی کل، ٹیکس اور کل کے لیے 'اظہار'۔ اظہار صرف پڑھنے کے لیے ہے اور بنیادی طور پر حسابی اقدار کو ظاہر کرنے کے لیے استعمال کیا جاتا ہے۔ SurveyJS جامد مواد کے لیے قسم: 'html' کو بھی سپورٹ کرتا ہے، لیکن حسابی اقدار کے لیے اظہار صحیح انتخاب ہے۔ اب ردعمل کی طرف۔ رینڈرنگ اور جمع کروانا بہت سادہ۔ وائر onComplete کو اپنے API پر اسی طرح استعمال کریں - استعمال کے ذریعے تبدیلی یا سادہ بازیافت:
"react" سے { useState, useEffect, useRef } درآمد کریں؛ "@tanstack/react-query" سے { useMutation } درآمد کریں؛ "survey-core" سے { Model } درآمد کریں؛ "survey-react-ui" سے { Survey } درآمد کریں؛ "survey-core/survey"؛ درآمد کریں
ایکسپورٹ فنکشن SurveyForm() { const [model] = useState(() => new Model(surveySchema))؛
const mutation = useMutation({ mutationFn: async (data) => { const res = انتظار کریں بازیافت ("/api/orders"، { طریقہ: "پوسٹ"، ہیڈر: { "مواد کی قسم": "درخواست/json" }، باڈی: JSON.stringify(data)، }); اگر (!res.ok) نئی خرابی پھینک دیں("جمع کرانے میں ناکام")؛ واپسی res.json(); }، });
const mutationRef = useRef(mutation)؛ mutationRef.current = mutation؛ useEffect(() => { const handler = (sender) => mutationRef.current.mutate(sender.data)؛ model.onComplete.add(handler)؛ واپسی () => model.onComplete.remove(handler)؛ }, [model]); // ref ہر رینڈر ہینڈلر کو دوبارہ رجسٹر کرنے سے گریز کرتا ہے (میوٹیشن آبجیکٹ کی شناخت میں تبدیلی)
واپسی ( <> <سروے ماڈل={ماڈل} /> {mutation.isError &&
Pen SurveyJS-03-SurveyJS دیکھیں
onComplete فائر ہوتا ہے جب صارف آخری نظر آنے والے صفحہ کے آخر تک پہنچ جاتا ہے۔ لہذا اگر ٹوٹل کبھی بھی 100 سے تجاوز نہیں کرتا ہے اور جائزہ کا صفحہ چھوڑ دیا جاتا ہے، تب بھی یہ صحیح طریقے سے فائر کرتا ہے کیونکہ SurveyJS یہ فیصلہ کرنے سے پہلے مرئیت کا جائزہ لیتا ہے کہ "آخری صفحہ" کا کیا مطلب ہے۔ پھر، sender.data تمام جوابات کے ساتھ حساب شدہ قدروں (ذیلی کل، ٹیکس، کُل) کو فرسٹ کلاس فیلڈز کے طور پر رکھتا ہے، اس لیے API کا پے لوڈ وہی ہے جو RHF ورژن کو onSubmit میں دستی طور پر جمع کیا گیا ہے۔ دیmutationRef پیٹرن وہی ہے جس کے لیے آپ کسی بھی جگہ پہنچیں گے جس کے لیے آپ کو ایک مستحکم ایونٹ ہینڈلر کی ضرورت ہے جو کہ ہر رینڈر پر تبدیل ہوتی ہے — اس کے بارے میں سروے جے ایس کے لیے مخصوص نہیں۔
React جزو میں اب کوئی کاروباری منطق نہیں ہے۔ کوئی استعمال واچ نہیں ہے، کوئی مشروط JSX نہیں، کوئی سٹیپ کاؤنٹر نہیں، کوئی میمو چین نہیں، کوئی سپر ریفائن نہیں۔ React وہی کر رہا ہے جس میں یہ اصل میں اچھا ہے: ایک جزو کو پیش کرنا اور اسے API کال پر وائرنگ کرنا۔ رد عمل سے باہر کیا منتقل ہوا؟
تشویش آر ایچ ایف اسٹیک سروے جے ایس مرئیت JSX شاخیں نظر آتا ہے اگر اخذ کردہ اقدار استعمال واچ / میمو استعمال کریں۔ اظہار کراس فیلڈ قوانین سپر ریفائن اسکیما کی شرائط نیویگیشن قدم ریاست صفحہ نظر آتا ہے اگر اصول کا مقام فائلوں میں تقسیم اسکیما میں مرکزیت
React میں جو چیز باقی رہتی ہے وہ ہے لے آؤٹ، اسٹائلنگ، سبمیشن وائرنگ، اور ایپ انٹیگریشن، جس کا کہنا ہے کہ React جن چیزوں کے لیے ڈیزائن کیا گیا ہے۔ باقی سب کچھ اسکیما میں منتقل ہوگیا، اور چونکہ اسکیما صرف ایک JSON آبجیکٹ ہے، اس لیے اسے ڈیٹا بیس میں اسٹور کیا جاسکتا ہے، آپ کے ایپلیکیشن کوڈ سے آزادانہ طور پر ورژن بنایا جاسکتا ہے، یا کسی تعیناتی کی ضرورت کے بغیر داخلی ٹولنگ کے ذریعے ترمیم کی جاسکتی ہے۔ ایک پروڈکٹ مینیجر جس کو اس حد کو تبدیل کرنے کی ضرورت ہے جو نظرثانی کے صفحے کو متحرک کرتی ہے وہ جزو کو چھوئے بغیر ایسا کر سکتا ہے۔ یہ ٹیموں کے لیے ایک بامعنی آپریشنل فرق ہے جہاں فارم کا رویہ کثرت سے تیار ہوتا ہے اور ہمیشہ انجینئرز کے ذریعے نہیں چلتا ہے۔ ہر ایک نقطہ نظر کا استعمال کب کرنا ہے؟ یہاں انگوٹھے کا ایک اچھا اصول ہے جو میرے لئے کام کرتا ہے: فارم کو مکمل طور پر حذف کرنے کا تصور کریں۔ آپ کیا کھویں گے؟
اگر یہ اسکرینیں ہیں، تو آپ اجزاء سے چلنے والی شکلیں چاہتے ہیں۔ اگر یہ کاروباری منطق ہے، جیسے دہلیز، برانچنگ کے اصول، اور مشروط تقاضے جو حقیقی فیصلوں کو انکوڈ کرتے ہیں، تو آپ کو اسکیما انجن چاہیے۔
اسی طرح، اگر آپ کے راستے میں آنے والی تبدیلیاں زیادہ تر لیبلز، فیلڈز اور لے آؤٹ کے بارے میں ہیں، تو RHF آپ کی اچھی خدمت کرے گا۔ اگر وہ شرائط، نتائج، اور قواعد کے بارے میں ہیں جو آپ کے آپریشنز یا قانونی ٹیم کو ٹکٹ فائل کیے بغیر منگل کی سہ پہر کو ایڈجسٹ کرنے کی ضرورت پڑ سکتی ہے، تو SurveyJS کے ساتھ اسکیما ماڈل زیادہ ایماندارانہ فٹ ہے۔ یہ دونوں نقطہ نظر واقعی ایک دوسرے کے ساتھ مقابلہ میں نہیں ہیں۔ وہ مسائل کے مختلف طبقوں کو حل کرتے ہیں، اور جس غلطی سے گریز کرنا ضروری ہے وہ ہے تجرید کو منطق کے وزن سے مماثل رکھنا — اصول کے نظام کو ایک جزو کی طرح برتاؤ کیونکہ یہ مانوس ٹول ہے، یا پالیسی انجن تک پہنچنا کیونکہ ایک فارم تین مراحل تک بڑھتا ہے اور ایک مشروط فیلڈ حاصل کرتا ہے۔ ہم نے یہاں جو فارم بنایا ہے وہ جان بوجھ کر باؤنڈری کے قریب بیٹھا ہے، فرق کو ظاہر کرنے کے لیے کافی پیچیدہ لیکن اتنا زیادہ نہیں کہ موازنہ میں دھاندلی محسوس ہو۔ زیادہ تر حقیقی شکلیں جو آپ کے کوڈبیس میں ناقابل برداشت ہو گئی ہیں شاید اسی حد کے قریب بیٹھی ہیں، اور سوال عام طور پر صرف یہ ہوتا ہے کہ کیا کسی نے نام دیا ہے کہ وہ اصل میں کیا ہیں۔ React Hook Form + Zod استعمال کریں جب:
فارم CRUD پر مبنی ہیں؛ منطق اتلی اور UI سے چلنے والی ہے۔ انجینئرز تمام طرز عمل کے مالک ہیں۔ پس منظر سچائی کا ذریعہ رہتا ہے۔
SurveJS استعمال کریں جب:
فارمز کاروباری فیصلوں کو انکوڈ کرتا ہے۔ قواعد UI سے آزادانہ طور پر تیار ہوتے ہیں۔ منطق مرئی، قابل سماعت، یا ورژن والی ہونی چاہیے۔ غیر انجینئرز رویے پر اثر انداز ہوتے ہیں؛ ایک ہی فارم کو متعدد فرنٹ اینڈ پر چلنا چاہیے۔