Режими на работа преку состојби на компоненти-потомци во React
Нека нашиот производен низа сега изгледа на следниов начин:
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'},
];
Ајде да ги прикажеме овие производи во форма на HTML
табела. Истовремено, ќе направиме така што при кликнување
на која било ќелија од табелата во таа ќелија да се појави
влезно поле за уредување. За да ја решите задачата
ќе направиме 3 компоненти.
Компонентата Products ќе ја чува состојбата
со производите и ќе ги користи компонентите Product
за приказ на производите. Компонентата Product
пак ќе ги користи компонентите
ProductField за приказ на одредено
поле на производот (име, цена, категорија).
Компонентата ProductField или ќе
го прикажува текстот на полето, или влезно поле за негово
уредување. Притоа, режимот на уредување
или приказ нека се регулира со состојбата
на оваа компонента.
Односно, ние нема да го чуваме режимот во родителската состојба. Таму тоа би било многу незгодно, бидејќи ќе треба да го наведеме режимот за секое поле на производот, што би ја претворило нашата состојба во нешто слично на ова:
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},
],
]
Ние, сепак, нема да направиме ваква состојба,
туку ќе ја оставиме онаа што беше. Едноставно, секоја
инстанца на компонентата ProductField
со помош на својата состојба ќе го регулира
режимот: или уредување, или приказ.
На овој начин ќе испадне дека родителската компонента ќе ја чува состојбата со податоците, а нашата компонента-внук ќе ги добива овие податоци преку пропси и притоа ќе има своја состојба за промена на својот режим.
Значи, ајде да го имплементираме опишаното.
Компонента 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>;
}
Компонента 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>;
}
Компонента 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>;
}
Практични задачи
Извршете ги сличните операции со компонентите
Users и User, создадени од вас
во претходните лекции.