Darbo režimai per vaikinių komponentų būsenas React
Tarkime, mūsų produktų masyvas dabar atrodo taip:
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'},
];
Išveskime šiuos produktus HTML
lentelės pavidalu. Tuo pačiu padarykime taip, kad paspaudus
bet kurį lentelės langelį, šiame langelyje atsirastų
įvesties laukas redagavimui. Užduočiai išspręsti
sukursime 3 komponentus.
Komponentas Products saugos būseną
su produktais ir naudos komponentus Product
produktų išvedimui. Komponentas Product
savo ruožtu taip pat naudos komponentus
ProductField tam tikro
produkto lauko (pavadinimo, kainos, kategorijos) išvedimui.
Komponentas ProductField rodys arba
lauko tekstą, arba įvesties lauką jo
redagavimui. Tuo tarpu redagavimo režimas
arba rodymas tebūnie reguliuojamas šio komponento
būsenos.
Tai yra, mes nesaugosime režimo tėvinėje būsenoje. Ten tai būtų labai nepatogu, nes mums tektų nurodyti režimą kiekvienam produkto laukui, kas paverstų mūsų būseną į kažką panašaus:
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},
],
]
Tačiau mes nedarysime tokios būsenos,
o paliksime tą, kuri buvo. Tiesiog kiekvienas
komponento ProductField atvejis
naudodamasis savo būsena reguliuos
režimą: arba redagavimą, arba rodymą.
Taip išeis, kad tėvinis komponentas saugos būseną su duomenimis, o mūsų anūkinis komponentas gaus šiuos duomenis per propsus ir tuo pačiu turės savo būseną savo režimui keisti.
Taigi, įgyvendinkime aprašytą.
Komponentas 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>;
}
Komponentas 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>;
}
Komponentas 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>;
}
Praktinės užduotys
Atlikite analogiškus veiksmus su komponentais
Users ir User, kuriuos sukūrėte
ankstesnėse pamokose.