Komponentide alamkomponentide olekute kaudu töötamise režiimid Reactis
Oletame, et meie toodete massiiv näeb nüüd välja järgmiselt:
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'},
];
Kuvame need tooted HTML
tabelina. Teeme seda nii, et klõpsates
suvalisel tabeli lahtril, ilmuks sellesse lahtrisse
sisestusväli redigeerimiseks. Ülesande lahendamiseks
teeme 3 komponenti.
Komponent Products hoiab olekut
toodetega ja kasutab komponente Product
toodete kuvamiseks. Komponent Product
omakorda kasutab ka komponente
ProductField konkreetse
toote välja kuvamiseks (nimi, hind, kategooria).
Komponent ProductField kuvab kas
välja teksti või sisestusvälja selle
redigeerimiseks. Samas režiim redigeerimine
või kuvamine olgu reguleeritud selle komponendi
olekuga.
See tähendab, et me ei salvesta režiimi vanema olekus. Seal oleks see väga ebamugav, kuna me peaksime määrama režiimi iga toode välja jaoks, mis muudaks meie oleku millegiks selliseks:
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},
],
]
Me aga ei tee sellist olekut,
vaid jätame selle, mis oli. Lihtsalt iga
komponendi ProductField eksemplar
oma oleku abil reguleerib
režiimi: kas redigeerimine või kuvamine.
Seega selgub, et vanemkomponent salvestab olekus andmed, ja meie lapselapskomponent saab need andmed läbi propside ja samas omab oma olekut oma režiimi muutmiseks.
Nii, teostame kirjeldatu.
Komponent 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>;
}
Komponent 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>;
}
Komponent 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>;
}
Praktilised ülesanded
Tehke samased toimingud komponentidega
Users ja User, mille olete loonud
eelmistes õppetundides.