रिएक्ट में चाइल्ड कंपोनेंट्स की स्टेट्स के माध्यम से कार्य मोड

मान लें कि अब हमारा उत्पादों की सरणी निम्नलिखित तरीके से दिखती है:

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 कंपोनेंट्स के साथ समान ऑपरेशन करें, जिन्हें आपने पिछले पाठों में बनाया था।