Ота-она компонентдаги стейтни болалар компонентида тахрирлаш 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>;
}

Энди тахрирлаш режимида маълумотлар билан инпутлар, оддий режимда эса спанлар бўлишини таъминлаймиз:

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 компонентларингиз билан ҳам шу операцияларни бажаринг.