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):
const 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:
function 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:
function 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:
function 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:
function 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:
function 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:
function 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:
function 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:
const 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:
function 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.