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 კომპონენტებზე, რომლებიც თქვენ შექმენით წინა გაკვეთილებში.