Darbības režīmi, izmantojot apakškomponentu stāvokļus React
Pieņemsim, ka mūsu produktu masīvs tagad izskatās šādi:
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'},
];
Parādīsim šos produktus HTML tabulas veidā.
Vienlaikus izveidosim tā, lai, noklikšķinot uz
jebkuras tabulas šūnas, šajā šūnā parādītos
ievades lauks rediģēšanai. Lai atrisinātu uzdevumu,
izveidosim 3 komponentus.
Komponents Products glabās stāvokli
ar produktiem un izmantos komponentus Product
produktu attēlošanai. Savukārt komponents Product
arī izmantos komponentus
ProductField, lai attēlotu noteiktu
produkta lauku (nosaukumu, cenu, kategoriju).
Komponents ProductField rādīs vai nu
lauka tekstu, vai ievades lauku tā
rediģēšanai. Šajā gadījumā rediģēšanas režīms
vai attēlošana ļaujiet regulēt šī komponenta stāvoklim.
Tas ir, mēs nenoguldīsim režīmu vecāku stāvoklī. Tur tas būtu ļoti neērti, jo mums būtu jānorāda režīms katram produkta laukam, kas pārvērstu mūsu stāvokli par kaut ko līdzīgu šim:
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},
],
]
Tomēr mēs neveidosim šādu stāvokli,
bet atstāsim to, kas bija. Vienkārši katrs
ProductField komponenta instances
ar sava stāvokļa palīdzību regulēs
režīmu: vai nu rediģēšanu, vai attēlošanu.
Tādējādi izrādīsies, ka vecāku komponents glabās stāvokli ar datiem, un mūsu mazmazkomponents saņems šos datus caur īpašībām (props) un vienlaikus būs savs stāvoklis, lai mainītu savu režīmu.
Tātad, īstenosim aprakstīto.
Komponents 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>;
}
Komponents 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>;
}
Komponents 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>;
}
Praktiskie uzdevumi
Veiciet līdzīgas darbības ar komponentiem
Users un User, ko izveidojāt
iepriekšējās nodarbībās.