React-এ প্যারেন্ট স্টেট চাইল্ড কম্পোনেন্টে পরিবর্তন করা

পূর্ববর্তী পাঠে, আমাদের ডেটা সহ স্টেট প্যারেন্ট কম্পোনেন্টে সংরক্ষণ করা ছিল, এবং চাইল্ড কম্পোনেন্টগুলি প্রপ্স的形式ে সেই ডেটা পেয়েছিল।

এখন ধরুন আমরা আমাদের পণ্যগুলি পরিবর্তন করতে চাই। উদাহরণস্বরূপ, একটি বাটন তৈরি করা যাক যা আমাদের পণ্যকে কার্টে রাখবে। শুরুতে আসুন আমাদের পণ্যের অ্যারেতে একটি ফিল্ড যোগ করি inCart, যা দেখাবে পণ্যটি কার্টে আছে কি না:

jsxconst initProds = [
  {id: id(), name: 'product1', cost: 100, inCart: false},
  {id: id(), name: 'product2', cost: 200, inCart: false},
  {id: id(), name: 'product3', cost: 300, inCart: false},
];

Products কম্পোনেন্টে, পণ্য সহ ট্যাগে আরও একটি অ্যাট্রিবিউট inCart যোগ করি:

jsxfunction Products() {
  const [prods, setProds] = useState(initProds);
  
  const items = prods.map(prod => {
    return <Product
      key   ={prod.id}
      name  ={prod.name}
      cost  ={prod.cost}
      inCart={prod.inCart}
    />;
  });
  
  return <div>
    {items}
  </div>;
}

আসুন চাইল্ড কম্পোনেন্ট Product-এ কার্ট সম্পর্কে তথ্য এবং কার্টে যোগ করার জন্য একটি বাটন তৈরি করি:

jsxfunction Product({ id, name, cost, inCart }) {
  return <div>
    name: <span>{name}</span>,
    cost: <span>{cost}</span>,
    <span>{inCart ? 'in cart' : 'not in cart'}</span>
    <button>to cart</button>
  </div>;
}

যোগ করা বাস্তবায়ন করি

React-এর নিয়ম অনুসারে, একটি কম্পোনেন্টের নিজস্ব প্রপ্স পরিবর্তন করা উচিত নয়। এর অর্থ চাইল্ড কম্পোনেন্ট নিজে থেকে inCart প্রপ্স পরিবর্তন করে নিজেকে কার্টে রাখতে পারে না। এটি সঠিক নয়।

সঠিক উপায় হবে প্যারেন্ট কম্পোনেন্টকে তার prods স্টেট পরিবর্তন করতে বলে, একটি নির্দিষ্ট পণ্যকে কার্টে রাখতে।

আসুন দেখি কিভাবে এটি করা হয়।

প্যারেন্ট কম্পোনেন্টে, আসুন একটি ফাংশন addToCart তৈরি করি, যা প্যারামিটার হিসাবে পণ্যের id নেয় এবং সেই পণ্যের জন্য inCart প্রপার্টি true-এ পরিবর্তন করে:

jsxfunction addToCart(id) {
  setProds(prods.map(prod => {
    if (prod.id === id) {
      prod.inCart = true;
    }
    
    return prod;
  }));
}

পণ্য সহ ট্যাগে, আমরা একটি অ্যাট্রিবিউট যোগ করব, যেখানে আমরা আমাদের তৈরি করা ফাংশনটি পাস করব, এবং এছাড়াও একটি অ্যাট্রিবিউট, যেখানে আমরা পণ্যের id পাস করব:

jsxconst items = prods.map(prod => {
  return <Product
    key      ={prod.id}
    id       ={prod.id}
    name     ={prod.name}
    cost     ={prod.cost}
    inCart   ={prod.inCart}
    addToCart={addToCart}
  />;
});

আপনি দেখতে পাচ্ছেন, কম্পোনেন্টের প্রপ্স-এ শুধুমাত্র কিছু ডেটা নয়, বরং ফাংশনও পাঠানো যায়।

Products ক্লাসের চূড়ান্ত কোড হবে নিম্নরূপ:

jsxfunction Products() {
  const [prods, setProds] = useState(initProds);
  
  function addToCart(id) {
    setProds(prods.map(prod => {
      if (prod.id === id) {
        prod.inCart = true;
      }
      
      return prod;
    }));
  }
  
  const items = prods.map(prod => {
    return <Product
      key      ={prod.id}
      id       ={prod.id}
      name     ={prod.name}
      cost     ={prod.cost}
      inCart   ={prod.inCart}
      addToCart={addToCart}
    />;
  });
  
  return <div>
    {items}
  </div>;
}

এখন চাইল্ড ক্লাসে আমাদের কাছে addToCart ফাংশনটি অ্যাক্সেসযোগ্য হবে। বাটনে ক্লিক করলে এই ফাংশনটি কল করি, এটিকে প্যারামিটার হিসাবে পণ্যের id পাস করে:

jsxfunction Product({ id, name, cost, inCart, addToCart }) {
  return <div>
    name: <span>{name}</span>,
    cost: <span>{cost}</span>,
    <span>{inCart ? 'in cart' : 'not in cart'}</span>
    <button onClick={() => addToCart(id)}>to cart</button>
  </div>;
}

এর ফলে, চাইল্ড কম্পোনেন্টে বাটনে ক্লিক করলে প্যারেন্টের ফাংশন কল হবে, যা প্যারেন্ট স্টেট পরিবর্তন করবে। প্যারেন্ট স্টেটের পরিবর্তন রি-রেন্ডারিং ঘটাবে এবং পরিবর্তিত প্রপ্স পাস করে আমাদের পণ্যকে পুনরায় রেন্ডার করবে।

Задание 1

পূর্ববর্তী পাঠ থেকে User কম্পোনেন্টটি নিন। এটিতে এমন করুন যাতে ব্যবহারকারীকে বান করার জন্য একটি বাটন উপস্থিত হয়।