⊗jsrtPmCpChPS 87 of 112 menu

Modificare lo stato del genitore in un componente figlio in React

Nella lezione precedente, lo stato con i dati era memorizzato nel componente genitore, mentre i componenti figli ricevevano questi dati sotto forma di props.

Ora supponiamo di voler modificare i nostri prodotti. Creiamo, ad esempio, un pulsante che aggiunga il nostro prodotto al carrello. Per iniziare aggiungiamo al nostro array di prodotti un campo inCart, che indica se il prodotto è nel carrello o meno:

const initProds = [ {id: id(), name: 'product1', cost: 100, inCart: false}, {id: id(), name: 'product2', cost: 200, inCart: false}, {id: id(), name: 'product3', cost: 300, inCart: false}, ];

Nel componente Products, aggiungiamo un altro attributo inCart al tag del prodotto:

function Products() { const [prods, setProds] = useState(initProds); const items = prods.map(prod => { return <Product key ={prod.id} name ={prod.name} cost ={prod.cost} inCart={prod.inCart} />; }); return <div> {items} </div>; }

Creiamo nel componente figlio Product un output per l'informazione sul carrello e un pulsante per l'aggiunta al carrello:

function Product({ id, name, cost, inCart }) { return <div> name: <span>{name}</span>, cost: <span>{cost}</span>, <span>{inCart ? 'in cart' : 'not in cart'}</span> <button>to cart</button> </div>; }

Implementiamo l'aggiunta

Secondo le regole di React, un componente non dovrebbe modificare le sue props. Ciò significa che un componente figlio non può aggiungere sé stesso al carrello modificando la prop inCart. Non è corretto.

Il modo corretto è chiedere al componente genitore di modificare il suo stato prods, impostando un determinato prodotto come nel carrello.

Vediamo come si fa.

Nel componente genitore, creiamo una funzione addToCart, che accetta come parametro l'id del prodotto e per quel prodotto cambia la proprietà inCart in true:

function addToCart(id) { setProds(prods.map(prod => { if (prod.id === id) { prod.inCart = true; } return prod; })); }

Aggiungiamo al tag del prodotto un attributo, in cui passiamo la funzione da noi creata, e anche un attributo, in cui passiamo l'id del prodotto:

const items = prods.map(prod => { return <Product key ={prod.id} id ={prod.id} name ={prod.name} cost ={prod.cost} inCart ={prod.inCart} addToCart={addToCart} />; });

Come puoi vedere, nei props dei componenti è possibile passare non solo alcuni dati, ma anche funzioni.

Il codice finale del componente Products risulterà il seguente:

function Products() { const [prods, setProds] = useState(initProds); function addToCart(id) { setProds(prods.map(prod => { if (prod.id === id) { prod.inCart = true; } return prod; })); } const items = prods.map(prod => { return <Product key ={prod.id} id ={prod.id} name ={prod.name} cost ={prod.cost} inCart ={prod.inCart} addToCart={addToCart} />; }); return <div> {items} </div>; }

Ora nella classe figlio avremo a disposizione la funzione addToCart. Chiamiamo questa funzione al click del pulsante, passandole come parametro l'id del prodotto:

function Product({ id, name, cost, inCart, addToCart }) { return <div> name: <span>{name}</span>, cost: <span>{cost}</span>, <span>{inCart ? 'in cart' : 'not in cart'}</span> <button onClick={() => addToCart(id)}>to cart</button> </div>; }

Il risultato sarà che al click sul pulsante nel figlio verrà chiamata la funzione del genitore, che cambierà lo stato del genitore. La modifica dello stato del genitore causerà un re-rendering e ridisegnerà il nostro prodotto, passandogli la prop modificata.

Prendi il componente User dalla lezione precedente. Fai in modo che appaia un pulsante per bannare l'utente.

Italiano
AfrikaansAzərbaycanБългарскиবাংলাБеларускаяČeštinaDanskDeutschΕλληνικάEnglishEspañolEestiSuomiFrançaisहिन्दीMagyarՀայերենIndonesia日本語ქართულიҚазақ한국어КыргызчаLietuviųLatviešuМакедонскиMelayuမြန်မာNederlandsNorskPolskiPortuguêsRomânăРусскийසිංහලSlovenčinaSlovenščinaShqipСрпскиSrpskiSvenskaKiswahiliТоҷикӣไทยTürkmenTürkçeЎзбекOʻzbekTiếng Việt
Utilizziamo i cookie per il funzionamento del sito, l'analisi e la personalizzazione. I dati vengono elaborati in conformità con la Politica sulla privacy.
accetta tutto personalizza rifiuta