Charakterization টেস্ট, ছোট নিরাপদ ধাপ এবং state উল্টে নিয়ে React কম্পোনেন্টগুলো Claude Code দিয়ে কিভাবে স্ট্রাকচার উন্নত রাখা যায়—বিহেভিয়ার না বদলে।

React রিফ্যাক্টরগুলো ঝুঁকিপূর্ণ লাগে কারণ অনেক কম্পোনেন্ট ছোট, পরিষ্কার বিল্ডিং ব্লক নয়। এগুলো UI, state, effects, এবং “আরেকটা prop” ফিক্স নিয়ে জটlated। স্ট্রাকচার বদলালে আপনি অনিচ্ছায় timing, identity, বা data flow বদলে ফেলতে পারেন।
রিফ্যাক্টর সবচেয়ে বেশি তখনই আচরণ বদলে দেয় যখন অনিচ্ছাকৃতভাবে ঘটে:\n
key বদলে গেলে state রিসেট হয়।রিফ্যাক্টররা রিরাইটে পরে যায় যখন “ক্লিনআপ” এবং “ইমপ্রুভমেন্ট” একসাথে মিশে যায়। আপনি উপাদান বের করা শুরু করেছেন, তারপর অনেক নাম বদলান, তারপর স্টেট শেপ “ফিক্স” করেন, তার পরে একটি হুক বদলান। খুব শীঘ্রই লেআউট ও লজিক একসঙ্গে বদলে যায়। গার্ডরেইল না থাকলে বোঝা কঠিন কোন পরিবর্তন বাগ সৃষ্টি করেছে।
একটি নিরাপদ রিফ্যাক্টরের একটিই প্রতিশ্রুতি থাকে: ব্যবহারকারীরা একই আচরণ পায়, এবং আপনার কোড আরো পরিষ্কার হয়। Props, ইভেন্ট, লোডিং স্টেট, এরর স্টেট, এবং এজ কেসগুলো একইভাবে আচরণ করা উচিত। যদি আচরণ বদলে যায়, সেটা ইচ্ছাকৃত, ছোট এবং স্পষ্টভাবে বলা থাকা উচিত।
যদি আপনি Claude Code (অথবা কোনো কোডিং অ্যাসিস্ট্যান্ট) দিয়ে React কম্পোনেন্ট রিফ্যাক্টর করছেন, তাকে দ্রুত পেয়ার প্রোগ্রামারের মতো বিবেচনা করুন, অটোপাইলট না। তাকে বলুন ঝুঁকি বর্ননা করতে, ছোট ছোট স্টেপের পরিকল্পনা প্রস্তাব করতে, এবং কিভাবে সে পরীক্ষা করেছে যে আচরণ অপরিবর্তিত আছে তা ব্যাখ্যা করতে। তারপর নিজেও যাচাই করুন: অ্যাপ চালান, অদ্ভুত পাথগুলো ক্লিক করুন, এবং এমন টেস্টগুলির উপর নির্ভর করুন যা বর্তমান কম্পোনেন্ট কী করে তা ধরে রাখে, আপনি যা চান তা নয়।
একটি কম্পোনেন্ট বেছে নিন যা আপনাকে সময় খায়। পুরো পেজ নয়, "UI লেয়ার" নয়, এবং নয় অস্পষ্ট "ক্লিনআপ"। একটি একক কম্পোনেন্ট বেছে নিন যেটা পড়তে কষ্ট করে, পরিবর্তন করতে কষ্ট করে, বা ভঙ্গুর state ও side effects দিয়ে ভর্তি। একটি সংকীর্ণ লক্ষ্য অ্যাসিস্ট্যান্টের প্রস্তাব যাচাই করা সহজ করে।
একটি লক্ষ্য লিখুন যা পাঁচ মিনিটে চেক করা যায়। ভাল লক্ষ্যগুলো স্ট্রাকচারের সম্পর্কে হয়, আউটকাম নয়: “ছোট কম্পোনেন্টে বিভাজন”, “স্টেট সহজ করে তোলা”, বা “মক ছাড়া টেস্ট করা যায় এমন করা।” "বহুত ভাল করা" বা "পারফরমেন্স বাড়ানো" মত অস্পষ্ট লক্ষ্য এড়িয়ে চলুন যদি না নির্দিষ্ট মেট্রিক ও বোতলনেক থাকে।
এডিট খুলার আগে বাউন্ডারি স্থাপন করুন। সবচেয়ে নিরাপদ রিফ্যাক্টরগুলো নीरস:
তারপর সেই ডিপেন্ডেন্সিগুলো তালিকাভুক্ত করুন যা কোড সরানোর সময় নীরবে আচরণ ভেঙে দিতে পারে: API কল, context providers, routing params, feature flags, analytics events, এবং শেয়ার করা গ্লোবাল স্টেট।
একটি কংক্রিট উদাহরণ: আপনার কাছে একটি 600-লাইনের OrdersTable আছে যা ডেটা ফেচ করে, ফিল্টার করে, সিলেকশন ম্যানেজ করে, এবং ডিটেইলস দেখাতে একটি drawer দেখায়। একটি স্পষ্ট লক্ষ্য হতে পারে: “row rendering এবং drawer UI বের করে ফেলো কম্পোনেন্টে, এবং সিলেকশন স্টেট একটি reducer-এ নিয়ে যাও, কোনো UI পরিবর্তন ছাড়াই।” সেই লক্ষ্য বলে দেয় কবে কাজ শেষ এবং কি scope-এর বাইরে।
রিফ্যাক্টরের আগে কম্পোনেন্টটিকে ব্ল্যাকবক্স হিসেবে বিবেচনা করুন। আপনার কাজ হলো আজ এটা কী করে তা ক্যাপচার করা, আপনি যা চান তা নয়। এটা রিফ্যাক্টরকে রিডিজাইন হয়ে যাওয়া থেকে রক্ষা করে।
শুরুতে বর্তমান আচরণ সাদাসিধে ভাষায় লিখুন: এই ইনপুট দিলে UI এই আউটপুট প্রদর্শন করে। প্রপস, URL প্যারাম, ফিচার ফ্ল্যাগ, এবং context বা স্টোর থেকে আসা যেকোন ডেটা অন্তর্ভুক্ত করুন। যদি আপনি Claude Code ব্যবহার করেন, একটি ছোট, ফোকাসড স্নিপেট পেস্ট করে এটি কে বলুন যাতে সে আচরণটিকে স্পষ্ট বাক্যে পুনরায় বলবে যা পরে চেক করা যাবে।
UI স্টেটগুলো কভার করুন যেগুলো মানুষ আসলে দেখে। একটি কম্পোনেন্ট হ্যাপি পাথে ঠিক দেখলেও লোডিং, এম্পটি বা এরর হলে ভেঙে যেতে পারে।
এছাড়াও ইমপ্লিসিট নিয়মগুলো ধরে রাখুন যা মিস করা সহজ এবং প্রায়ই রিফ্যাক্টর ভাঙায়:
উদাহরণ: একটি ইউজার টেবিল আছে যা রেজাল্ট লোড করে, সার্চ সাপোর্ট করে, এবং “Last active” দিয়ে সোর্ট করে। লিখে রাখুন সার্চ খালি হলে কি হয়, API খালি লিস্ট দিলে কি হয়, API এরর হলে কি হয়, এবং যদি দুই ইউজারের “Last active” একই হয় তখন কি হয়। ছোট ট্রিকস—সোর্ট কি case-insensitive, ফিল্টার পরিবর্তনে টেবিল কি পেজ ধরে রাখে—এসবও নোট করুন।
নোটগুলো যখন বিরক্তিকরভাবে ও নির্দিষ্ট মনে হবে, তখন আপনি রেডি।
Characterization tests হলো “আজ এটি কী করে” এমন টেস্ট। এগুলো বর্তমান আচরণ বর্ণনা করে, এমনকি যদি সেটা ভিন্ন বা ভবিষ্যতে পরিবর্তনযোগ্য না হয়। এটা উল্টোদিক মনে হলেও, এটা রিফ্যাক্টরকে চুপচাপ রিরাইটে রূপান্তর হওয়া থেকে রক্ষা করে।
Claude Code দিয়ে রিফ্যাক্টর করার সময় এই টেস্টগুলো আপনার সেফটি রেইল। টুল কোডreshape করতে সাহায্য করবে, কিন্তু সিদ্ধান্ত আপনি নিবেন কোনটা অপরিবর্তিত থাকবে।
ইউজার এবং অন্য কোড কী নির্ভর করে তার উপর ফোকাস করুন:
টেস্টগুলো স্থিতিশীল রাখতে, ইমপ্লিমেন্টেশন নয় আউটকাম assert করুন। “Save বাটন disable হয় এবং একটি মেসেজ দেখায়” ভালো, “setState কল হয়েছে” নয়। যদি টেস্ট ব্রেক করে কারণ আপনি কম্পোনেন্টের নাম বদলে দিয়েছেন বা হুকগুলোর অর্ডার বদলে দিয়েছেন, তাহলে সেটা আচরণ রক্ষা করছে না।
অ্যাসিঙ্ক আচরণই সবচেয়ে ঝুঁকিপূর্ণ—টাইমিং বদলে যেতে পারে। স্পষ্টভাবে ট্রিট করুন: UI স্থিতিশীল হওয়া পর্যন্ত অপেক্ষা করুন, তারপর assert করুন। যদি টাইমার থাকে (debounced search, delayed toasts), fake timers ব্যবহার করুন এবং সময় এগিয়ে দিন। নেটওয়ার্ক কল থাকলে fetch mock করুন এবং সাফল্য ও ব্যর্থতার পরে ইউজার কি দেখে তা assert করুন। Suspense-স্টাইল ফ্লো থাকলে fallback এবং resolved view দুটোই টেস্ট করুন।
উদাহরণ: একটি “Users” টেবিল “No results” দেখায় শুধুমাত্র সার্চ শেষে। একটি characterization টেস্ট সেই সিকোয়েন্স লক করবে: প্রথমে লোডিং ইনডিকেটর, তারপর রো বা empty মেসেজ—কোনো পদ্ধতি দ্বারা আপনি পরে কম্পোনেন্ট ভাগই করলে যেন তা বজায় থাকে।
জয় হল “বড় পরিবর্তন দ্রুত” নয়। জয় হল কম্পোনেন্ট কোনটা করে তা স্পষ্ট করে দেখা, তারপর এক ছোট জিনিস করে আচরণ ধরে রাখা।
শুরুতে কম্পোনেন্ট পেস্ট করে তার দায়িত্বের plain-English সারাংশ চাইুন। বিশেষভাবে চাপ দিন: কি ডেটা দেখায়, কি ইউজার ক্রিয়াকলাপ হ্যান্ডল করে, এবং কি সাইড ইফেক্ট ট্রিগার করে (fetching, timers, subscriptions, analytics)। প্রায়ই এই ধাপটি লুকানো কাজগুলো উন্মোচন করে যা রিফ্যাক্টরকে ঝুঁকিপূর্ণ করে।
এরপর dependency map চান। প্রতিটি ইনপুট ও আউটপুটের ইনভেন্টরি চান: props, context reads, custom hooks, local state, derived values, effects, এবং মডিউল-লেভেল হেল্পার। একটি ভাল ম্যাপ বলে দেবে কি মুভ করা নিরাপদ (pure calculations) এবং কি “স্টিকি” (টাইমিং, DOM, নেটওয়ার্ক)।
তারপর extraction candidate প্রস্তাব চান, একটি কড়া নিয়ম সহ: pure view অংশগুলি stateful কন্ট্রোলার অংশ থেকে আলাদা করুন। JSX-ভারি সেকশন যেগুলো শুধুই props লাগে সেগুলোই প্রথম বের করার যোগ্য। ইভেন্ট হ্যান্ডলার, অ্যাসিঙ্ক কল, এবং state আপডেট মিশ্রিত করে এমন সেকশনগুলো সাধারণত নয়।
একটি করে workflow যা বাস্তবে টিকে যায়:
চেকপয়েন্ট গুরুত্বপূর্ণ। Claude Code–কে একটি মিনিমাল প্ল্যান চান যেখানে প্রতিটি স্টেপ commit ও revert করা যায়। একটি বাস্তবচেকপয়েন্ট হতে পারে: “<TableHeader> extract করো কোন লজিক পরিবর্তন ছাড়াই” তারপর sorting state-এ হাত দেওয়ার আগে।
কংক্রিট উদাহরণ: যদি একটি কম্পোনেন্ট কাস্টমার টেবিল রেন্ডার করে, ফিল্টার নিয়ন্ত্রণ করে, এবং ডেটা ফেচ করে—প্রথমে table markup (headers, rows, empty state) একটি pure component-এ extract করুন। তারপর filter state বা fetch effect নিয়ে কাজ করুন। এই অর্ডার বাগকে JSX–এর সাথে ভ্রমণ করতে দেয় না।
বড় কম্পোনেন্ট ভাগ করার সময় ঝুঁকি শুধুই JSX নড়াচড়া নয়—ঝুঁকি ডেটা ফ্লো, টাইমিং, বা ইভেন্ট ওয়্যারিং অনিচ্ছাকৃতভাবে বদলে দেওয়া। প্রথমে extraction–কে copy-and-wire হিসেবে বিবেচনা করুন, এবং পরে ক্লিনআপ করুন।
উইথি UI তে যে বাউন্ডারি আছে সেগুলো খুঁজুন, ফাইল স্ট্রাকচারের মধ্যে নয়। এমন অংশ খুঁজুন যেগুলো আপনি বাক্যে একা “একটা জিনিস” বলে বর্ণনা করতে পারবেন: অ্যাকশন সহ হেডার, ফিল্টার বার, রেজাল্ট লিস্ট, ফুটার উইথ পেজিং।
নিরাপদ প্রথম পদক্ষেপ হলো pure presentational components বের করা: props ইন, JSX আউট। বোঝাপড়া করে বাধ্যতামূলকভাবে বিরক্তিকর রাখুন—কোনো নতুন state নয়, কোনো নতুন effect নয়, কোনো নতুন API কল নয়। যদি মূল কম্পোনেন্টে একটি ক্লিক হ্যান্ডলার থাকে যা তিনটা কাজ করে, সেই হ্যান্ডলার প্যারেন্টেই রাখুন এবং নিচে পাঠান।
নামকরণ মানুষের ভাবনায় বেশি প্রভাব ফেলে। স্পেসিফিক নাম দিন যেমন UsersTableHeader বা InvoiceRowActions। "Utils" বা "HelperComponent" মত জেনেরিক নাম এড়িয়ে চলুন—এগুলো দায়িত্ব লুকায় এবং কনসার্ন মিক্স করতে উত্সাহ দেয়।
কোনো কন্টেনার কম্পোনেন্ট প্রবর্তন তখনই করুন যখন ওটা সত্যিই স্টেট বা এফেক্ট own করার প্রয়োজন তৈরি করে। তা হলে ওটাও সংকীর্ণ রাখুন—একটি কন্টেনার এক কাজে অধিকতর নির্দিষ্ট হওয়া উচিত (যেমন “filter state”) এবং সবকিছু প্রপস হিসেবে পাঠাবে।
গন্ডোগলানো কম্পোনেন্টগুলো সাধারণত তিন ধরনের ডেটা মিশিয়ে ফেলে: আসল UI state (যা ব্যবহারকারী বদলে), derived data (যা আপনি compute করতে পারেন), এবং server state (নেটওয়ার্ক থেকে আসে)। সবকিছু লোকাল state হিসেবে ধরলে রিফ্যাক্টর ঝুঁকিপূর্ণ হয় কারণ আপনি অনিচ্ছায় আপডেটের সময় বদলে দিতে পারেন।
শুরুতেই প্রতিটি ডেটা টুকরোকে লেবেল করুন। জিজ্ঞেস করুন: ব্যবহারকারী এটা এডিট করে, না আমি props/state/fetched data থেকে compute করতে পারি? এবং এটা এখানেই own করা কি, নাকি কেবল পাস করা হচ্ছে?
derived মান useState-এ রাখা উচিত নয়। সেগুলো একটি ছোট ফাংশনে বা খরচবহুল হলে memoized selector-এ নিয়ে যান। এতে state আপডেট কমবে এবং আচরণ পড়তে সহজ হবে।
একটি নিরাপদ প্যাটার্ন:
useState-এ রাখুন।useMemo বেঁধে দিন।effects তখনই আচরণ ভাঙে যখন ওরা অনেক কাজ করে বা ভুল ডিপেন্ডেন্সিতে রিয়্যাক্ট করে। উদ্দেশ্য রাখুন: এক কাজের জন্য এক effect—একটা localStorage sync, একটা fetching, একটা subscription। যদি একটি effect অনেক মান পড়ে, সেটি প্রায়ই অতিরিক্ত দায়িত্ব লুকায়।
Claude Code ব্যবহার করলে একটি ছোট পরিবর্তন চাওয়ান: একটি effectকে দুইটে বিভক্ত করুন, বা একটি দায়িত্ব হেল্পারে সরান। তারপর প্রতিটি মুভের পরে characterization tests চালান।
prop drilling–এর ক্ষেত্রে সাবধানে হোন। context ব্যবহার তখনই সাহায্য করে যখন এটা repeated wiring কমায় এবং ownership স্পষ্ট করে। ভালো সংকেত হলো context যখন অ্যাপ-লেভেলের ধারণা বোঝায় (current user, theme, feature flags), না যে কেবল একটি কম্পোনেন্ট ট্রি–এর ওয়ার্কঅ্যারাউন্ড।
উদাহরণ: একটি টেবিল কম্পোনেন্ট rows ও filteredRows উভয়ই state-এ রাখতে পারে। rows state-এ রাখুন, filteredRows rows+query থেকে compute করুন, এবং ফিল্টারিং কোডটি একটি pure ফাংশনে রাখুন যাতে টেস্ট করা সহজ এবং ভাঙ্গা কঠিন হয়।
রিফ্যাক্টর সবচেয়ে বেশি ভুল হয় যখন আপনি অনেক কিছু একসাথে বদলে ফেলেন আগে বোঝার। সমাধানটি সহজ: ছোট চেকপয়েন্টে কাজ করুন, এবং প্রতিটি চেকপয়েন্টকে একটি মিনি-রিলিজ মনে করুন। এমনকি একটি ব্রাঞ্চে কাজ করলে ও, আপনার পরিবর্তনগুলো PR-সাইজের রাখুন যাতে আপনি দেখতে পারেন কি ভেঙেছে আর কেন।
প্রতিটি তাৎপর্যপূর্ণ মুভের পরে (একটি কম্পোনেন্ট extract করা, state flow বদলানো) থামুন এবং প্রমাণ করুন আপনি আচরণ বদলাননি। প্রমাণটি হতে পারে টেস্ট (অটোমেটেড) এবং ম্যানুয়াল (ব্রাউজারে দ্রুত চেক)। লক্ষ্য নিখুঁততা নয়—লক্ষ্য দ্রুত সনাক্তকরণ।
একটি ব্যবহারিক চেকপয়েন্ট লুপ:
যদি আপনি Koder.ai-এর মতো প্ল্যাটফর্ম ব্যবহার করেন, স্ন্যাপশট ও rollback আপনাকে iteration চলাকালীন সেফ্টি রেইল হিসেবে কাজ করবে। তবুও সাধারণ commits রাখা উচিত, কিন্তু স্ন্যাপশট তুলনা করার সময় বা এক্সপেরিমেন্ট খারাপ হলে দ্রুত ফিরে আসার জন্য সাহায্য করে।
চলন্তে একটি ছোট বিবরণী রাখুন—কি যাচাই করেছেন—এটি এক নোট মাত্র এবং বারবার একই জিনিস চেক করা রোধ করে।
উদাহরণ:
যখন কিছু ভেঙে যায়, লেজার্ড আপনাকে বলে কি পুনরায় চেক করতে হবে এবং আপনার চেকপয়েন্টগুলো রিভার্ট করতে সস্তা করে তোলে।
অধিকাংশ রিফ্যাক্টর ছোট, নীরস উপায়ে ব্যর্থ হয়। UI এখনও কাজ করে, কিন্তু একটি স্পেসিং নিয়ম নেই, একটি ক্লিক হ্যান্ডলার ডাবল ফায়ার করে, অথবা টাইপিং হওয়ার সময় তালিকা ফোকাস হারায়। অ্যাসিস্ট্যান্টরা এটা আরও কঠিন করতে পারে কারণ কোড পরিষ্কার দেখায় যদিও আচরণ ধীরে ধীরে বদলে যাচ্ছে।
একটি সাধারণ কারণ স্ট্রাকচার পরিবর্তন: আপনি একটি কম্পোনেন্ট extract করে অতিরিক্ত <div> র্যাপ করেন, বা <button> বদলে clickable <div> ব্যবহার করেন। CSS সিলেক্টর, লেআউট, কীবোর্ড নেভিগেশন, এবং টেস্ট কয়েরিগুলো পরিবর্তিত হতে পারে বিনা সতর্কতায়।
সবচেয়ে প্রায়ই ভাঙে এমন ফাঁদগুলো:
{} বা () => {}) তৈরি করলে অতিরিক্ত re-render এবং child state রিসেট হতে পারে। আগে যেগুলো স্থিতিশীল ছিল সেই props-এ নজর রাখুন।useEffect, useMemo, বা useCallback-এ সরালে stale value বা loop আসতে পারে যদি ডিপেন্ডেন্সি ভুল হয়। একটি effect যদি আগের মত “on click” চলতো, এটাকে "whenever anything changes" করা যাবেনা।কংক্রিট উদাহরণ: টেবিল কম্পোনেন্ট split করে এবং রো কী ইনডেক্সে বদলে দিলে তা ভাল লাগতে পারে, কিন্তু যখন রো reorder হয় তখন সিলেকশন ভাংতে পারে। “ক্লিন” কে বোনাস মনে করুন। “একই আচরণ” হল প্রয়োজনীয়তা।
মার্জ করার আগে প্রমাণ চান যে রিফ্যাক্টর আচরণ অপরিবর্তিত রেখেছে। সবচেয়ে সহজ সিগন্যাল বিরক্তিকর: সবকিছু এখনও কাজ করে এবং আপনাকে টেস্ট “ফিক্স” করতে হয়নি।
শেষ ছোট পরিবর্তনের পরে এই দ্রুত পাস চালান:
onChange এখন মাউন্টে নয়, ইউজার ইনপুটে ট্রিগার হয়)।একটি দ্রুত স্যানিটি চেক: কম্পোনেন্ট খুলে একটি অদ্ভুত ফ্লো চালান—যেমন error ট্রিগার, retry, তারপর ফিল্টার ক্লিয়ার করা। রিফ্যাক্টরগুলি প্রায়শই ট্রানজিশন ভেঙে দেয় যদিও প্রধান পথ কাজ করে।
যদি কিছু ফেল করে, শেষ পরিবর্তন revert করুন এবং ছোট ধাপে পুনরায় করুন। এটা বড় ডিফ ডিবাগ করার চেয়ে সাধারণত দ্রুত।
ভাবুন একটি ProductTable আছে যা সবকিছু করে: ডেটা ফেচ করে, ফিল্টার ম্যানেজ করে, পেজিং নিয়ন্ত্রণ করে, ডিলিট কনফার্ম ডায়ালগ দেখায়, এবং রো অ্যাকশন (edit, duplicate, archive) হ্যান্ডেল করে। এটি ছোট শুরু করে 900-লাইনের ফাইল হয়ে দাঁড়িয়েছে।
লক্ষণীয়: state scattered across useState কল, কয়েকটি useEffect নির্দিষ্ট ক্রমে চলে, এবং একটি “harmless” পরিবর্তন পেজিং ভেঙে দেয় যখন একটি ফিল্টার সক্রিয় থাকে। মানুষ এটাকে স্পর্শ করা বন্ধ করে দেয় কারণ এটি অনির্ভরযোগ্য মনে হয়।
স্ট্রাকচার বদলানোর আগে কয়েকটি React characterization tests লক করুন। ব্যবহারকারীর কাজগুলোতে মনোযোগ দিন, ইন্টার্নাল state নয়:
এখন ছোট কমিটে রিফ্যাক্টর করুন। একটি পরিষ্কার extraction প্ল্যান হতে পারে: FilterBar কন্ট্রোল রেন্ডার করে এবং ফিল্টার চেঞ্জ ইমিট করে; TableView রো ও পেজিং রেন্ডার করে; RowActions action মেনু এবং কনফার্ম ডায়ালগ UI ধরে; এবং একটি useProductTable হুক কঠিন লজিক (query params, derived state, side effects) ধারণ করে।
অর্ডার গুরুত্বপূর্ণ। প্রথমে dumb UI বের করুন (TableView, FilterBar) প্রপস অপরিবর্তিত রেখে। ঝুঁকিপূর্ণ অংশ শেষেই রাখুন: state ও effects useProductTable-এ নিয়ে যাওয়া। যখন করবেন, পুরনো প্রপ নাম ও ইভেন্ট শেপ রাখুন যাতে টেস্ট চলতেই থাকে। যদি টেস্ট ভেঙে, সেটা একটি আচরণ পরিবর্তন ধরা—স্টাইল ইস্যু নয়।
আপনি যদি Claude Code নিয়ে React কম্পোনেন্ট রিফ্যাক্টরিং প্রতিবার নিরাপদ করতে চান, যা আপনি বিষয়টি শেষ করেছেন সেটাকে একটি ছোট টেমপ্লেটে রূপান্তর করুন। লক্ষ্য বেশি প্রসেস নয়—কম বিস্ময়।
একটি সংক্ষিপ্ত প্লেবুক লিখে রাখুন যা আপনি যে কোনও কম্পোনেন্টে অনুসরণ করতে পারেন:
এই টেমপ্লেটটি নোট বা রিপোতে স্নিপেট হিসেবে স্টোর করুন যাতে পরের রিফ্যাক্টর একই সেফটি রেইল দিয়ে শুরু হয়।
কম্পোনেন্ট স্টেবল ও পড়তে সহজ হয়েই পরের পাস ব্যবহারকারীর ইমপ্যাক্ট অনুযায়ী নির্ধারণ করুন। সাধারণ অর্ডার: অ্যাক্সেসিবিলিটি প্রথম (লেবেল, ফোকাস, কিবোর্ড), তারপর পারফরম্যান্স (memoization, ব্যয়বহুল রেন্ডার), তারপর ক্লিনআপ (টাইপ, নামকরণ, ডেড কোড)। এক PR–এ তিনটি মিক্স করবেন না।
আপনি যদি Koder.ai (koder.ai)–এর স্ন্যাক-ওয়ার্কফ্লো ব্যবহার করেন, planning mode-এ ধাপগুলি আউটলাইন করতে পারবেন, স্ন্যাপশট ও rollback চেকপয়েন্ট হিসেবে ব্যবহার করতে পারবেন। শেষ হলে সোর্স এক্সপোর্ট করে ফাইনাল ডিফ রিভিউ করা সহজ হয় এবং history পরিষ্কার থাকে।
বেঠিক সময় থামুন যখন টেস্টগুলো সেই আচরণ কভার করে যেটা আপনি ভাঙতে ভয় পাচ্ছেন, পরবর্তী পরিবর্তন নতুন ফিচার হবে, বা আপনি একটি PR-এ পারফেকশনিস্ট হয়ে উঠবেন। যদি বড় ফর্ম থেকে tangled state সরিয়ে ফেলা হয় এবং আপনার টেস্ট ভ্যালিডেশন ও সাবমিট কভার করে, ship করুন এবং বাকি আইটেমগুলো ব্যাকলগ হিসেবে রাখুন।
React রিফ্যাক্টরিং প্রায়ই আইডেন্টিটি এবং টাইমিং পরিবর্তন করে যার দিকে আমরা নজর দিই না। সাধারণ ব্রেকেজগুলো:
key বদলে যাওয়ায় state রিসেট হওয়া।কোনও পরিবর্তন নিশ্চিত না হওয়া পর্যন্ত ধরে নিন যে স্ট্রাকচারাল পরিবর্তন আচরণ বদলে দিতে পারে।
সংকীর্ণ, চেক করা যায় এমন স্ট্রাকচারাল লক্ষ্য রাখুন, ফলাফল না। ভাল লক্ষ্যগুলোর উদাহরণ:
"বেটার করো" ধাঁচের অস্পষ্ট লক্ষ্য এড়িয়ে চলুন যদি না আপনার কাছে নির্দিষ্ট মেট্রিক বা বোতলনেক জানা থাকে।
কম্পোনেন্টকে ব্ল্যাকবক্স হিসেবে বিবেচনা করুন এবং ব্যবহারকারীর পর্যবেক্ষণযোগ্য আচরণ লিখে রাখুন:
এই নোটগুলো যতটা বoring মনে হবে, ততটাই উপকারী।
Characterization tests যোগ করুন—এগুলো বর্ণনা করে কম্পোনেন্ট আজ কী করে, এমনকি যদি সেটা অদ্ভুতই কেন না চলুক।
প্রায়োগিক লক্ষ্য:
UI-তে ফলাফল অ্যাসার্ট করুন, ইন্টার্নাল হুক কল নয়।
Claude Code–কে সাবধানে পেয়ার প্রোগ্রামারের মতো ব্যবহার করুন:
বড় একবারে রিরাইট-স্টাইল diff গ্রহণ করবেন না; ইনক্রিমেন্টাল পরিবর্তন চাইতে চাপ দিন।
প্রথমে pure presentational অংশগুলো বের করুন:
প্রথমে copy-and-wire করুন; পরে ধাপে ধাপে ক্লিনআপ করবেন। UI আলাদা করার পরে state/effects নিয়ে কাজ করুন।
স্টেবল আইডেন্টিটি (যেমন ID) পছন্দ করুন, অ্যারে ইনডেক্স নয়।
ইনডেক্স কীগুলো তখনই “চলতে” থাকে যতক্ষণ না আপনি sort, filter, insert বা remove করেন—তারপর React ভুল ইনস্ট্যান্স reuse করতে পারে এবং দেখা যায়:
আপনি যদি রিফ্যাক্টরে কী বদলান, সেটা উচ্চ রিস্ক হিসেবে ধরুন এবং reorder কেস টেস্ট করুন।
যতটা সম্ভব derived মান useState-এ রাখবেন না—পছন্দমতো compute করুন।
নিরাপদ পদ্ধতি:
চেকপয়েন্ট রাখুন যাতে প্রতিটি ধাপ দ্রুত revert করা যায়:
এই লুপটি বড় ডিফ ডিবাগ করার চেয়ে দ্রুত আর নিরাপদ।
থামুন যখন:
রিফ্যাক্টরটি ship করুন এবং বাকি আইটেমগুলো (অ্যাক্সেসিবিলিটি, পারফরম্যান্স, ক্লিনআপ) আলাদা কাজ হিসেবে রাখুন।
filteredRowsrowsqueryuseMemo ব্যবহার করুনএভাবে আপডেটের অদ্ভুততা কমে এবং কোড পড়তে সহজ হয়।