React-এ চাইল্ড কম্পোনেন্টের স্টেটের মাধ্যমে কাজ করার মোড

ধরি আমাদের পণ্যের অ্যারেটি এখন দেখতে নিম্নরূপ:

jsxconst initProds = [
  {id: id(), name: 'prod1', cost: 'cost1', catg: 'catg1'},
  {id: id(), name: 'prod2', cost: 'cost2', catg: 'catg2'},
  {id: id(), name: 'prod3', cost: 'cost3', catg: 'catg3'},
];

আসুন এই পণ্যগুলোকে HTML টেবিল আকারে দেখাই। এবং এটি এমনভাবে করি যাতে টেবিলের যেকোনো সেলে ক্লিক করলে সেই সেলে এডিট করার জন্য একটি ইনপুট উপস্থিত হয়। সমস্যাটি সমাধান করতে আমরা 3টি কম্পোনেন্ট তৈরি করব।

Products কম্পোনেন্টটি পণ্যগুলোর সাথে তার স্টেট সংরক্ষণ করবে এবং Product কম্পোনেন্ট ব্যবহার করবে পণ্য দেখানোর জন্য। Product কম্পোনেন্টটি আবার ProductField কম্পোনেন্টগুলোও ব্যবহার করবে পণ্যের একটি নির্দিষ্ট ফিল্ড (নাম, মূল্য, বিভাগ) দেখানোর জন্য।

ProductField কম্পোনেন্টটি হয় ফিল্ডের টেক্সট দেখাবে, অথবা এটিকে এডিট করার জন্য একটি ইনপুট দেখাবে। এক্ষেত্রে এডিট মোড বা প্রদর্শন মোড এই কম্পোনেন্টের স্টেট দ্বারা নিয়ন্ত্রিত হবে।

অর্থাৎ আমরা মোডটি প্যারেন্ট স্টেটে সংরক্ষণ করব না। সেখানে এটি খুবই অসুবিধাজনক হত, কারণ আমাদের প্রতিটি পণ্যের ফিল্ডের জন্য মোড উল্লেখ করতে হত, যা আমাদের স্টেটকে এমন কিছুতে পরিণত করত:

jsxconst initProds = [
  [
    {field: 'name', value: 'prod1', isEdit: false},
    {field: 'cost', value: 'cost1', isEdit: false},
    {field: 'catg', value: 'catg1', isEdit: false},
  ],
  [
    {field: 'name', value: 'prod2', isEdit: false},
    {field: 'cost', value: 'cost2', isEdit: false},
    {field: 'catg', value: 'catg2', isEdit: false},
  ],
  [
    {field: 'name', value: 'prod3', isEdit: false},
    {field: 'cost', value: 'cost3', isEdit: false},
    {field: 'catg', value: 'catg3', isEdit: false},
  ],
]

যাইহোক, আমরা এমন স্টেট করব না, বরং যে স্টেট ছিল সেটিই রাখব। শুধু প্রতিটি ProductField কম্পোনেন্টের উদাহরণ তার নিজস্ব স্টেট ব্যবহার করে মোড নিয়ন্ত্রণ করবে: হয় এডিটিং মোড, অথবা প্রদর্শন মোড।

এইভাবে ফলাফল হবে যে, প্যারেন্ট কম্পোনেন্ট ডেটা সহ স্টেট সংরক্ষণ করবে, আর আমাদের নাতি-কম্পোনেন্টটি এই ডেটা প্রপ্সের মাধ্যমে পাবে এবং একই সাথে তার নিজের মোড পরিবর্তনের জন্য নিজস্ব স্টেট রাখবে।

সুতরাং, আসুন বর্ণিত বিষয়টি বাস্তবায়ন করি।

Products কম্পোনেন্ট

jsxfunction Products() {
  const [prods, setProds] = useState(initProds);
  
  function changeField(id, field, event) {
    setProds(prods.map(prod => {
      if (prod.id === id) {
        prod[field] = event.target.value;
      }
      
      return prod;
    }));
  }
  
  const rows = prods.map(prod => {
    return <Product
      key ={prod.id}
      id  ={prod.id}
      name={prod.name}
      cost={prod.cost}
      catg={prod.catg}
      changeField={changeField}
    />;
  });
  
  return <div>
    <table>
      <tbody>
        {rows}
      </tbody>
    </table>
  </div>;
}

Product কম্পোনেন্ট

jsxfunction Product({ id, name, cost, catg, changeField }) {
  return <tr>
    <ProductField id={id} text={name} type="name" changeField={changeField} />
    <ProductField id={id} text={cost} type="cost" changeField={changeField} />
    <ProductField id={id} text={catg} type="catg" changeField={changeField} />
  </tr>;
}

ProductField কম্পোনেন্ট

jsxfunction ProductField({ id, text, type, changeField }) {
  const [isEdit, setIsEdit] = useState(false);
  
  return <td>
    {
      isEdit
      ? <input
        value={text}
        onChange={event => changeField(id, type, event)}
        onBlur={() => setIsEdit(false)}
      />
      : <span onClick={() => setIsEdit(true)}>{text}</span>
    }
  </td>;
}

ব্যবহারিক কাজ

Задание 1

আপনি পূর্ববর্তী পাঠে তৈরি করা Users এবং User কম্পোনেন্টগুলোর সাথে একই অপারেশন করুন।