Editarea stării părintelui în componenta copil în React
Să edităm acum produsele noastre cu ajutorul inputurilor. Pentru aceasta, în componenta copil să facem un buton.
La prima apăsare pe acest buton, în locul numelui și prețului cu produsul să apară inputuri pentru editarea lor, iar la a doua apăsare în locul inputurilor să apară din nou textele.
Să aducem o modificare în array-ul cu produse, adăugând
proprietatea isEdit (iar lucrul cu coșul
pentru simplitate îl vom elimina):
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},
];
Componenta Product
Să facem în produs un buton pentru editare:
jsxfunction Product({ id, name, cost, isEdit }) {
return <div>
name: <span>{name}</span>
cost: <span>{cost}</span>
<button>edit</button>
</div>;
}
Să facem astfel încât la click pe acest buton
să fie apelată o anumită funcție toggleMode,
transmisă din componenta părinte:
jsxfunction Product({ id, name, cost, isEdit, toggleMode }) {
return <div>
name: <span>{name}</span>
cost: <span>{cost}</span>
<button onClick={() => toggleMode(id)}>
edit
</button>
</div>;
}
Momentan nu avem implementarea pentru toggleMode,
dar știm că aceasta va fi situată
în componenta-părinte, ca parametru va primi
id-ul produsului și va modifica proprietatea isEdit
produsului la opus.
Să facem de asemenea astfel încât textul butonului să se schimbe la fiecare apăsare:
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>;
}
Să facem acum astfel încât în modul de editare să avem inputuri cu date, iar în modul normal - elemente 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>;
}
Să legăm de inputurile noastre evenimentul onChange,
în care vom apela o anumită funcție părinte
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>;
}
Componenta Products
Să trecem acum în componenta Products.
Să implementăm în ea funcția toggleMode:
jsxfunction toggleMode(id) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod.isEdit = !prod.isEdit;
}
return prod;
}));
}
De asemenea, să implementăm în ea funcția editProd:
jsxfunction editProd(id, field, event) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod[field] = event.target.value;
}
return prod;
}));
}
În tag-ul cu produsul, ca atribute să transmitem
funcțiile noastre toggleMode și 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}
/>;
});
Codul final al componentei Products
va fi următorul:
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>;
}
Probleme practice
Efectuați operațiuni similare cu componentele
Users și User, create de dvs.
în lecțiile anterioare.