Werkswyses deur state van kinderkomponente in React
Laat ons produk-array nou so lyk:
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'},
];
Kom ons vertoon hierdie produkte in 'n HTML-tabel.
Laat ons ook maak sodat wanneer op enige selle in die tabel geklik word,
'n invoerveld vir redigering in daardie sel verskyn.
Om die probleem op te los, sal ons 3 komponente maak.
Die komponent Products sal die state met produkte stoor
en die komponente Product gebruik om produkte te vertoon.
Die komponent Product sal op sy beurt ook komponente
ProductField gebruik om 'n spesifieke
produkveld (naam, prys, kategorie) te vertoon.
Die komponent ProductField sal óf
die teks van die veld wys, óf 'n invoerveld vir die
redigering daarvan.
Laat die redigerings- of vertoonmodus
gereguleer word deur die state
van hierdie komponent.
Dit beteken ons sal nie die modus in die ouer se state stoor nie. Dit sou baie ongerieflik wees daar, aangesien ons dan die modus vir elke produkveld sou moes spesifiseer, wat ons state in iets soos die volgende sou verander:
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},
],
]
Ons sal egter nie so 'n state maak nie,
maar die een wat daar was, behou.
Eenvoudig sal elke
instansie van die komponent ProductField
met behulp van sy eie state die
modus reguleer: óf redigering, óf vertoning.
Sodoende sal dit gebeur dat die ouerkomponent die state met data sal stoor, en ons kleinkind-komponent sal hierdie data deur props ontvang en terselfdertyd sal sy eie state hê om sy modus te verander.
Kom ons implementeer wat beskryf is.
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>;
}
Praktiese Take
Voer soortgelyke bewerkings uit met die komponente
Users en User wat jy geskep het
in vorige lesse.