React да компонент-авлодларининг стейтлари орқали ишлаш тарзлари
Энди бизнинг маҳсулотлар массивимиз quyidagicha кўриниши керак:
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 жадвал шаклида
чиқарайлик. Шу билан бирга, жадвалнинг istalgan
ячейкаси босиlganda, шу ячейкада тахрирлаш учун
инпут пайдо бўлишини таъминлаймиз. Масалани
ечиш учун 3 та компонент яратамиз.
Products компоненти маҳсулотлар билан
стейтни сақлайди ва Product компонентларидан
маҳсулотларни чиқариш учун фойдаланади. Product
компоненти ўз навбатида маълум бир маҳсулот
майдонини (номи, нархи, категорияси) чиқариш
учун ProductField компонентларидан фойдаланади.
ProductField компоненти ёки майдон
матинини кўрсатади, ёки уни тахрирлаш учун
инпутни кўрсатади. Шу билан бирга, тахрирлаш
режими ёки кўрсатиш ушбу компонентнинг
стейти томониidan tartibga солинсин.
Яъни биз режимни ота компонентнинг стейтида сақламеймиз. У ерда бу жуда ноqulay бўлар эди, чунки биз ҳар бир маҳсулот майдони учун режимни кўрсатишимиз керак бўлар эди, бу эса бизнинг стейтимизни quyidagiga ўхшаш нарсага айлантириб қўяр эди:
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},
],
]
Аммо биз бундай стейт яраtмаймиз,
балки аввалгисини қолдирамиз. Жуда оддийгина,
ProductField компонентининг ҳар бир
экземпляри ўз стейти ёрдамида режимни
tartibga солади: ёки тахрирлаш, ёки кўрсатиш.
Шундай қилиб, ота компонент маълумотлар билан стейтни сақлайди, бизнинг невара компоненти эса ушбу маълумотларни пропслар орқали олади ва шу билан бирга ўз режимини ўзгартириш учун ўз стейтига эга бўлади.
Шундай қилиб, келинг тавсифланганни амалга опирамиз.
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 компонентлари
билан ўхшаш амалиётларни бажаринг, уларни
сиз олдинги дарсларда яратган эдингиз.