⊗jsrtPmCpMVS 90 of 112 menu

Režimy práce přes stavy komponent-potomků v Reactu

Nechť naše pole s produkty nyní vypadá následovně:

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'}, ];

Vypišme tyto produkty ve formě HTML tabulky. Zároveň udělejme to, aby po kliknutí na libovolnou buňku tabulky se v této buňce objevilo vstupní pole pro editaci. Pro řešení úlohy vytvoříme 3 komponenty.

Komponenta Products bude uchovávat stav s produkty a používat komponenty Product pro výpis produktů. Komponenta Product bude naopak také používat komponenty ProductField pro výpis konkrétního pole produktu (názvu, ceny, kategorie).

Komponenta ProductField bude buď zobrazovat text pole, nebo vstupní pole pro jeho editaci. Přitom režim editace nebo zobrazení nechť je řízen stavem této komponenty.

To znamená, že režim nebudeme uchovávat v nadřazeném stavu. Tam by to bylo velmi nepohodlné, protože bychom museli uvádět režim pro každé pole produktu, což by proměnilo náš stav v něco podobného:

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}, ], ]

My však takový stav dělat nebudeme, a ponecháme ten, který byl. Jednoduše každá instance komponenty ProductField pomocí svého stavu bude řídit režim: buď editaci, nebo zobrazení.

Tak se stane, že nadřazená komponenta bude uchovávat stav s daty, a naše vnoučecí komponenta bude tato data získávat přes props a přitom bude mít svůj stav pro změnu svého režimu.

Takže, pojďme realizovat popsané.

Komponenta 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>; }

Komponenta 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>; }

Komponenta 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>; }

Praktické úlohy

Proveďte analogické operace s komponentami Users a User, vytvořenými vámi v předchozích lekcích.

Čeština
AfrikaansAzərbaycanБългарскиবাংলাБеларускаяDanskDeutschΕλληνικάEnglishEspañolEestiSuomiFrançaisहिन्दीMagyarՀայերենIndonesiaItaliano日本語ქართულიҚазақ한국어КыргызчаLietuviųLatviešuМакедонскиMelayuမြန်မာNederlandsNorskPolskiPortuguêsRomânăРусскийසිංහලSlovenčinaSlovenščinaShqipСрпскиSrpskiSvenskaKiswahiliТоҷикӣไทยTürkmenTürkçeЎзбекOʻzbekTiếng Việt
Používáme soubory cookie pro fungování webu, analýzu a personalizaci. Zpracování údajů probíhá v souladu s Zásadami ochrany osobních údajů.
přijmout vše přizpůsobit odmítnout