React में चाइल्ड कंपोनेंट में पैरेंट स्टेट को बदलना

पिछले पाठ में हमारे पास डेटा वाली स्थिति पैरेंट कंपोनेंट में संग्रहीत थी, और चाइल्ड कंपोनेंट्स को यह डेटा props के रूप में प्राप्त होता था।

अब मान लीजिए कि हम अपने उत्पादों को बदलना चाहते हैं। उदाहरण के लिए, एक बटन बनाते हैं जो हमारे उत्पाद को कार्ट में डालेगा। शुरुआत में आइए हम अपने उत्पादों की सरणी में एक फ़ील्ड 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 के नियमों के अनुसार किसी कंपोनेंट को अपने props को नहीं बदलना चाहिए। इसका मतलब है कि चाइल्ड कंपोनेंट स्वयं inCart prop को बदलकर खुद को कार्ट में नहीं डाल सकता। यह सही नहीं है।

सही तरीका यह होगा कि पैरेंट कंपोनेंट से अपनी स्थिति 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}
  />;
});

जैसा कि आप देख रहे हैं, कंपोनेंट के props में न केवल कुछ डेटा, बल्कि फ़ंक्शन भी पास किए जा सकते हैं।

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>;
}

ऐसा होगा कि चाइल्ड में बटन पर क्लिक करने पर पैरेंट का फ़ंक्शन कॉल होगा, जो पैरेंट की स्थिति को बदल देगा। पैरेंट की स्थिति में परिवर्तन से पुन: रेंडरिंग होगी और हमारे उत्पाद को फिर से बदला जाएगा, उसे बदला हुआ prop पास करके।

Задание 1

पिछले पाठ से User कंपोनेंट लें। इसे ऐसा बनाएं कि इसमें यूजर को बैन करने के लिए एक बटन दिखाई दे।