⊗jsrtPmCpChPS 87 of 112 menu

Cambiar el estado del componente padre en un componente hijo en React

En la lección anterior, el estado con los datos se almacenaba en el componente padre, y los componentes hijos recibían estos datos a través de props.

Ahora supongamos que queremos modificar nuestros productos. Hagamos, por ejemplo, un botón que agregue nuestro producto al carrito. Para empezar, agreguemos a nuestro array de productos el campo inCart, que indica si el producto está en el carrito o no:

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

En el componente Products, en la etiqueta del producto agreguemos otro atributo inCart:

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

Hagamos en el componente hijo Product la salida de información sobre el carrito y un botón para agregar al carrito:

function Product({ id, name, cost, inCart }) { return <div> name: <span>{name}</span>, cost: <span>{cost}</span>, <span>{inCart ? 'en el carrito' : 'no en el carrito'}</span> <button>al carrito</button> </div>; }

Implementemos la adición

Según las reglas de React, un componente no debe cambiar sus props. Esto significa que el componente hijo no puede agregarse a sí mismo al carrito cambiando la prop inCart. Esto no es correcto.

Lo correcto es pedir al componente padre que cambie su estado prods, colocando un producto determinado en el carrito.

Veamos cómo se hace.

En el componente padre, hagamos una función addToCart, que acepta como parámetro el id del producto y para ese producto cambia la propiedad inCart a true:

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

En la etiqueta del producto agreguemos un atributo, al cual le pasaremos la función que creamos, así como un atributo, al cual le pasaremos el id del producto:

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

Como puedes ver, en las props de los componentes se pueden pasar no solo datos, sino también funciones.

El código final de la función Products quedará así:

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

Ahora en la función hija tendremos disponible la función addToCart. Llamemos a esta función al hacer clic en el botón, pasándole como parámetro el id del producto:

function Product({ id, name, cost, inCart, addToCart }) { return <div> name: <span>{name}</span>, cost: <span>{cost}</span>, <span>{inCart ? 'en el carrito' : 'no en el carrito'}</span> <button onClick={() => addToCart(id)}>al carrito</button> </div>; }

El resultado será que al hacer clic en el botón en el componente hijo se llamará a la función del padre, que cambiará el estado del padre. El cambio del estado del padre provocará un rerenderizado y redibujará nuestro producto, pasándole la prop modificada.

Tome el componente User de la lección anterior. Haga que aparezca un botón para banear al usuario.

Español
AfrikaansAzərbaycanБългарскиবাংলাБеларускаяČeštinaDanskDeutschΕλληνικάEnglishEestiSuomiFrançaisहिन्दीMagyarՀայերենIndonesiaItaliano日本語ქართულიҚазақ한국어КыргызчаLietuviųLatviešuМакедонскиMelayuမြန်မာNederlandsNorskPolskiPortuguêsRomânăРусскийසිංහලSlovenčinaSlovenščinaShqipСрпскиSrpskiSvenskaKiswahiliТоҷикӣไทยTürkmenTürkçeЎзбекOʻzbekTiếng Việt
Usamos cookies para el funcionamiento del sitio, análisis y personalización. El procesamiento de datos se realiza de acuerdo con la Política de privacidad.
aceptar todas configurar rechazar