React এর হাতেখড়ি (পর্ব ১০) — একাধিক ফর্ম ইনপুট একসাথে হ্যান্ডল করা শিখুন

একাধিক ফর্ম ইনপুট single state object দিয়ে হ্যান্ডল করা

আগের পর্বে আমরা Controlled Component শিখেছিলাম। কিন্তু একটা ফর্মে ৫-৬টা ইনপুট থাকলে প্রতিটার জন্য আলাদা useState লিখতে হলে কোড অনেক লম্বা হয়ে যায়। এই পর্বে আমরা দেখব কীভাবে একটা single state object দিয়ে পুরো ফর্ম পরিচালনা করা যায়।

সমস্যাটা কী?

প্রতিটা ইনপুটের জন্য আলাদা state আর আলাদা হ্যান্ডলার লিখলে কোড দ্রুত বড় হয়ে যায়:

// ❌ প্রতিটা ইনপুটের জন্য আলাদা useState — ৫টা ইনপুটে ৫ জোড়া লাইন
function SignupForm() {
  const [name, setName] = React.useState("");
  const [email, setEmail] = React.useState("");
  const [phone, setPhone] = React.useState("");
  const [city, setCity] = React.useState("");
  const [bio, setBio] = React.useState("");

  return (
    <form>
      <input value={name} onChange={(e) => setName(e.target.value)} />
      <input value={email} onChange={(e) => setEmail(e.target.value)} />
      <input value={phone} onChange={(e) => setPhone(e.target.value)} />
      <input value={city} onChange={(e) => setCity(e.target.value)} />
      <textarea value={bio} onChange={(e) => setBio(e.target.value)} />
    </form>
  );
}

সমাধান — একটা Object State

Advanced JS পর্ব ৪-৫-এ শেখা Destructuring আর Spread এখানে একসাথে কাজে লাগবে — সব ইনপুটের ডেটা একটা মাত্র অবজেক্টে রাখা যায়।

function SignupForm() {
  const [formData, setFormData] = React.useState({
    name: "",
    email: "",
    phone: "",
    city: "",
    bio: ""
  });

  function handleChange(e) {
    const { name, value } = e.target; // ইনপুটের name অ্যাট্রিবিউট আর value
    setFormData({
      ...formData, // পুরনো সব ডেটা রাখা (Spread, Advanced JS পর্ব ৫)
      [name]: value // শুধু যেটা পাল্টেছে সেটা আপডেট (computed property name)
    });
  }

  return (
    <form>
      <input name="name" value={formData.name} onChange={handleChange} />
      <input name="email" value={formData.email} onChange={handleChange} />
      <input name="phone" value={formData.phone} onChange={handleChange} />
      <input name="city" value={formData.city} onChange={handleChange} />
      <textarea name="bio" value={formData.bio} onChange={handleChange} />
    </form>
  );
}

এখন যতগুলো ইনপুট থাকুক, শুধু একটা handleChange ফাংশনই সবকিছু সামলাচ্ছে!

handleChange কীভাবে কাজ করছে — বিস্তারিত

এই একটা ফাংশনের মধ্যে বেশ কয়েকটা গুরুত্বপূর্ণ কনসেপ্ট মিলে আছে:

function handleChange(e) {
  const { name, value } = e.target;
  // ১. e.target হলো যে ইনপুটে টাইপ করা হয়েছে
  // ২. name হলো সেই ইনপুটের "name" অ্যাট্রিবিউট (যেমন "email")
  // ৩. value হলো তাতে যা টাইপ করা হয়েছে

  setFormData({
    ...formData,
    [name]: value
    // "computed property name" — Advanced JS-এ দেখা হয়নি, নতুন কিছু
    // [name] মানে name ভ্যারিয়েবলের মান (যেমন "email") দিয়ে key বসানো
    // এটা আসলে { email: value } হয়ে যায়, যদি name === "email"
  });
}

নতুন জিনিস — Computed Property Name: { [name]: value }-এ [ ] ব্যবহার করে একটা ভ্যারিয়েবলের মান দিয়ে অবজেক্ট key বানানো যায়। এটা একটা সাধারণ JavaScript ফিচার (Advanced JS সিরিজে আমরা এটা সরাসরি কভার করিনি, কিন্তু এখানে খুব কাজে লাগছে)।

const fieldName = "email";
const fieldValue = "test@example.com";

// [fieldName] মানে key হবে fieldName-এর মান, "fieldName" স্ট্রিং না
const obj = { [fieldName]: fieldValue };
console.log(obj); // { email: "test@example.com" }

গুরুত্বপূর্ণ: এই প্যাটার্ন কাজ করার জন্য প্রতিটা ইনপুটে name অ্যাট্রিবিউট state-এর key-এর সাথে হুবহু মিলতে হবেname="email" মানে formData.email আপডেট হবে।

লাইভ ডেমো — একটা handleChange, পাঁচটা ইনপুট

নিচের যেকোনো ইনপুটে টাইপ করো — সবগুলো একই handleChange ফাংশন ব্যবহার করছে, নিচে পুরো state object সরাসরি দেখা যাচ্ছে।

checkbox হ্যান্ডেল করা — একটু ভিন্ন

Object state-এর সাথে checkbox মেলানোর সময় একটু সতর্ক থাকতে হয় — checkbox-এর মান value-তে না, checked-এ থাকে।

function handleChange(e) {
  const { name, value, type, checked } = e.target;

  setFormData({
    ...formData,
    [name]: type === "checkbox" ? checked : value
    // checkbox হলে checked ব্যবহার করো, নাহলে value
  });
}

// ব্যবহার
<input
  type="checkbox"
  name="subscribeNewsletter"
  checked={formData.subscribeNewsletter}
  onChange={handleChange}
/>

একটা নির্দিষ্ট ফিল্ড আলাদা করে পাল্টানো

সব ইনপুট একই handleChange ব্যবহার না করে চাইলে, নির্দিষ্ট একটা ফিল্ডও সরাসরি পাল্টানো যায়:

function resetEmailOnly() {
  setFormData({ ...formData, email: "" }); // শুধু email খালি করা, বাকি সব ঠিক থাকবে
}

function resetEntireForm() {
  setFormData({ name: "", email: "", phone: "", city: "", bio: "" }); // পুরো ফর্ম রিসেট
}

একটা সম্পূর্ণ উদাহরণ — বই যোগ করার ফর্ম

চলো Pathok Ghor-স্টাইল একটা "নতুন বই যোগ করো" ফর্ম বানাই, যেখানে একাধিক ইনপুট single state দিয়ে সামলানো হচ্ছে।

function AddBookForm() {
  const [book, setBook] = React.useState({
    title: "",
    author: "",
    pageCount: "",
    isFree: false
  });

  function handleChange(e) {
    const { name, value, type, checked } = e.target;
    setBook({
      ...book,
      [name]: type === "checkbox" ? checked : value
    });
  }

  function handleSubmit(e) {
    e.preventDefault();
    console.log("নতুন বই:", book);
    // এখানে actual সেভ করার কোড থাকবে
  }

  return (
    <form onSubmit={handleSubmit}>
      <input name="title" value={book.title} onChange={handleChange} placeholder="শিরোনাম" />
      <input name="author" value={book.author} onChange={handleChange} placeholder="লেখক" />
      <input name="pageCount" value={book.pageCount} onChange={handleChange} placeholder="পাতা সংখ্যা" type="number" />
      <label>
        <input name="isFree" checked={book.isFree} onChange={handleChange} type="checkbox" />
        ফ্রি বই
      </label>
      <button type="submit">যোগ করো</button>
    </form>
  );
}

এই একটা component-এ চারটা ভিন্ন ধরনের ইনপুট (text, text, number, checkbox) একটা মাত্র state object আর একটা মাত্র handleChange দিয়ে পরিচালিত হচ্ছে।

নিজে চেষ্টা করো

Exercise:

  1. উপরের AddBookForm নিজে বানাও, সাবমিট করলে console-এ ডেটা দেখো।
  2. একটা "সব ইনপুট খালি করো" বাটন যোগ করো, যেটা পুরো formData রিসেট করবে।
  3. একটা select ড্রপডাউন যোগ করো একই handleChange ব্যবহার করে (হিন্ট: select-এও name আর value একইভাবে কাজ করে)।
  4. উপরের লাইভ ডেমোতে একটা নতুন ইনপুট (যেমন phone) যোগ করো — লক্ষ্য করো handleChange ফাংশনে কোনো পরিবর্তন লাগে না।

পরের পর্বে যা থাকছে

পরের পর্বে আমরা শিখব Form Validation — error state ব্যবহার করে কীভাবে ফর্মে ভুল থাকলে ব্যবহারকারীকে জানানো যায়, আর সঠিকভাবে submit হ্যান্ডেল করা যায়।

একটি মন্তব্য পোস্ট করুন

নবীনতর পূর্বতন

যোগাযোগ ফর্ম