მშობელი კომპონენტის state-ის რედაქტირება შვილ კომპონენტში React-ში

მოდით ახლა ჩვენი პროდუქტები რედაქტირება ინფუთების საშუალებით. ამისთვის შვილ კომპონენტში გავაკეთოთ ღილაკი.

ამ ღილაკზე პირველი დაწკაპუნებისას დაესწაროს სახელისა და ფასის ნაცვლად პროდუქტთან გამოჩნდეს ინფუთები მათი რედაქტირებისთვის, ხოლო მეორე დაწკაპუნებისას ინფუთების ნაცვლად კვლავ გამოჩნდეს ტექსტები.

შევიტანოთ ცვლილება პროდუქტების მასივში, დავამატოთ თვისება isEdit (ხოლო კალათასთან მუშაობა სიმარტივისთვის ამოვიღოთ):

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

Product კომპონენტი

გავაკეთოთ პროდუქტში რედაქტირების ღილაკი:

jsxfunction Product({ id, name, cost, isEdit }) {
  return <div>
    name: <span>{name}</span>
    cost: <span>{cost}</span>
    <button>edit</button>
  </div>;
}

გავაკეთოთ ისე, რომ ამ ღილაკზე დაწკაპუნებისას გამოიძახოს რაღაც ფუნქცია toggleMode, რომელიც გადაეცემა მშობელი კომპონენტიდან:

jsxfunction Product({ id, name, cost, isEdit, toggleMode }) {
  return <div>
    name: <span>{name}</span>
    cost: <span>{cost}</span>
    
    <button onClick={() => toggleMode(id)}>
      edit
    </button>
  </div>;
}

ჩვენ ჯერ არ გვაქვს toggleMode-ის იმპლემენტაცია, მაგრამ ვიცით, რომ ის განთავსდება მშობელ კომპონენტში, პარამეტრად მიიღებს id პროდუქტის და შეცვლის თვისებას isEdit პროდუქტის საპირისპიროდ.

ასევე გავაკეთოთ ისე, რომ ღილაკის ტექსტი იცვლებოდეს ყოველ დაწკაპუნებაზე:

jsxfunction Product({ id, name, cost, isEdit, toggleMode }) {
  return <div>
    name: <span>{name}</span>
    cost: <span>{cost}</span>
    
    <button onClick={() => toggleMode(id)}>
      {isEdit ? 'save': 'edit'}
    </button>
  </div>;
}

მოდით ახლა გავაკეთოთ ისე, რომ რედაქტირების რეჟიმში გვქონდეს ინფუთები მონაცემებით, ხოლო ჩვეულ რეჟიმში - span-ები:

jsxfunction Product({ id, name, cost, isEdit, toggleMode }) {
  return <div>
    name: {isEdit ? <input value={name} /> : <span>{name}</span>}
    cost: {isEdit ? <input value={cost} /> : <span>{cost}</span>}
    
    <button onClick={() => toggleMode(id)}>
      {isEdit ? 'save': 'edit'}
    </button>
  </div>;
}

მოვახერხოთ ჩვენს ინფუთებს მოვლენა onChange, რომელშიც გამოვიძახებთ რაღაც მშობელ ფუნქციას editProd:

jsxfunction Product({ id, name, cost, isEdit, toggleMode, editProd }) {
  return <div>
    name: {
      isEdit
      ? <input value={name} onChange={event => editProd(id, 'name', event)} />
      : <span>{ name }</span>
    }
    cost: {
      isEdit
      ? <input value={cost} onChange={event => editProd(id, 'cost', event)} />
      : <span>{ cost }</span>
    }
    
    <button onClick={() => toggleMode(id)}>
      {isEdit ? 'save': 'edit'}
    </button>
  </div>;
}

Products კომპონენტი

მოდით ახლა გადავიდეთ Products კომპონენტში. რეალიზაცია გავუკეთოთ მასში ფუნქციას toggleMode:

jsxfunction toggleMode(id) {
  setProds(prods.map(prod => {
    if (prod.id === id) {
      prod.isEdit = !prod.isEdit;
    }
    
    return prod;
  }));
}

ასევე რეალიზაცია გავუკეთოთ მასში ფუნქციას editProd:

jsxfunction editProd(id, field, event) {
  setProds(prods.map(prod => {
    if (prod.id === id) {
      prod[field] = event.target.value;
    }
    
    return prod;
  }));
}

პროდუქტის თეგში ატრიბუტებად გადავცეთ ჩვენი ფუნქციები toggleMode და editProd:

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

Products კომპონენტის საბოლოო კოდი მიიღებს შემდეგ სახეს:

jsxfunction Products() {
  const [prods, setProds] = useState(initProds);
  
  function toggleMode(id) {
    setProds(prods.map(prod => {
      if (prod.id === id) {
        prod.isEdit = !prod.isEdit;
      }
      
      return prod;
    }));
  }
  
  function editProd(id, field, event) {
    setProds(prods.map(prod => {
      if (prod.id === id) {
        prod[field] = event.target.value;
      }
      
      return prod;
    }));
  }
  
  const result = prods.map(prod => {
    return <Product
      key ={prod.id}
      id  ={prod.id}
      name={prod.name}
      cost={prod.cost}
      isEdit={prod.isEdit}
      toggleMode={toggleMode}
      editProd={editProd}
    />;
  });
  
  return <div>
    {result}
  </div>;
}

პრაქტიკული ამოცანები

Задание 1

გააკეთეთ მსგავსი ოპერაციები კომპონენტებთან Users და User, რომლებიც თქვენ შექმნით წინა გაკვეთილებში.