Bewerking van ouer se staat in 'n kinderkomponent in React

Laat ons nou ons produkte redigeer met behulp van invoervelde. Om dit te doen, maak ons 'n knoppie in die kinderkomponent.

Met die eerste klik op hierdie knoppie, laat daar in plaas van die naam en prys met die produk, invoervelde verskyn vir die redigering daarvan, en met die tweede klik verskyn die teks weer in plaas van die invoervelde.

Laat ons veranderinge aanbring in die array met produkte, deur die eienskap isEdit by te voeg (en vir eenvoudigheid verwyder ons die werk met die mandjie):

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

Komponent Product

Laat ons 'n knoppie maak in die produk vir redigering:

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

Laat ons dit so maak dat met 'n klik op hierdie knoppie 'n sekere funksie toggleMode opgeroep word, wat van die ouerkomponent oorgedra is:

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

Ons het nog nie die implementering van toggleMode nie, maar ons weet dat dit sal geleë wees in die ouerkomponent, die id van die produk as parameter sal aanvaar en die eienskap isEdit sal verander van die produk na die teenoorgestelde.

Laat ons ook so maak dat die teks van die knoppie verander met elke klik:

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

Laat ons nou so maak dat in die redigeringsmodus ons invoervelde met data het, en in die gewone modus - span-elemente:

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

Laat ons aan ons invoervelde die gebeurtenis onChange koppel, waarin ons 'n sekere ouer funksie editProd sal aanroep:

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

Komponent Products

Laat ons nou na die komponent Products gaan. Implementeer daarin die funksie toggleMode:

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

Implementeer ook daarin die funksie editProd:

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

In die produk-tag, dra ons ons funksies toggleMode en editProd oor as attribute:

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

Die finale kode van die komponent Products sal soos volg wees:

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

Praktiese take

Задание 1

Doen soortgelyke bewerkings met die komponente Users en User, wat deur julle geskep is in vorige lesse.