Režimi rada kroz stanja komponenata-potomaka u React
Neka naš niz sa proizvodima sada izgleda na sledeći način:
const initProds = [
{id: id(), name: 'prod1', cost: 'cost1', catg: 'catg1'},
{id: id(), name: 'prod2', cost: 'cost2', catg: 'catg2'},
{id: id(), name: 'prod3', cost: 'cost3', catg: 'catg3'},
];
Hajde da prikažemo ove proizvode u vidu HTML
tabele. Pored toga, učinimo da po kliku
na bilo koju ćeliju tabele u toj ćeliji pojavi
input polje za izmenu. Za rešenje zadatka
napravićemo 3 komponente.
Komponenta Products će čuvati stanje
sa proizvodima i koristiti komponente Product
za prikaz proizvoda. Komponenta Product
će takođe koristiti komponente
ProductField za prikaz određenog
polja proizvoda (naziva, cene, kategorije).
Komponenta ProductField će ili
prikazivati tekst polja, ili input polje za njegovo
uređivanje. Pritom, režim uređivanja
ili prikaza neka bude regulisan stanjem
ove komponente.
To jest, nećemo čuvati režim u roditeljskom stanju. Tamo bi to bilo vrlo nezgodno, pošto bi morali da naznačimo režim za svako polje proizvoda, što bi pretvorilo naše stanje u nešto poput ovoga:
const initProds = [
[
{field: 'name', value: 'prod1', isEdit: false},
{field: 'cost', value: 'cost1', isEdit: false},
{field: 'catg', value: 'catg1', isEdit: false},
],
[
{field: 'name', value: 'prod2', isEdit: false},
{field: 'cost', value: 'cost2', isEdit: false},
{field: 'catg', value: 'catg2', isEdit: false},
],
[
{field: 'name', value: 'prod3', isEdit: false},
{field: 'cost', value: 'cost3', isEdit: false},
{field: 'catg', value: 'catg3', isEdit: false},
],
]
Mi, međutim, nećemo praviti takvo stanje,
već ćemo ostaviti ono koje je bilo. Jednostavno će svaka
instanca komponente ProductField
pomoću svog stanja regulisati
režim: bilo uređivanje, bilo prikaz.
Tako će ispasti da će roditeljska komponenta čuvati stanje sa podacima, a naša komponenta unuče primaće te podatke kroz pros i pritom će imati svoje stanje za promenu svog režima.
Dakle, hajde da implementiramo opisano.
Komponenta Products
function Products() {
const [prods, setProds] = useState(initProds);
function changeField(id, field, event) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod[field] = event.target.value;
}
return prod;
}));
}
const rows = prods.map(prod => {
return <Product
key ={prod.id}
id ={prod.id}
name={prod.name}
cost={prod.cost}
catg={prod.catg}
changeField={changeField}
/>;
});
return <div>
<table>
<tbody>
{rows}
</tbody>
</table>
</div>;
}
Komponenta Product
function Product({ id, name, cost, catg, changeField }) {
return <tr>
<ProductField id={id} text={name} type="name" changeField={changeField} />
<ProductField id={id} text={cost} type="cost" changeField={changeField} />
<ProductField id={id} text={catg} type="catg" changeField={changeField} />
</tr>;
}
Komponenta ProductField
function ProductField({ id, text, type, changeField }) {
const [isEdit, setIsEdit] = useState(false);
return <td>
{
isEdit
? <input
value={text}
onChange={event => changeField(id, type, event)}
onBlur={() => setIsEdit(false)}
/>
: <span onClick={() => setIsEdit(true)}>{text}</span>
}
</td>;
}
Praktični zadaci
Uradite slične operacije sa komponentama
Users i User, koje ste kreirali
u prethodnim lekcijama.