Muchas veces nos encontramos en la incertidumbre de como manejar el estado en nuestros componentes, la primera manera que solemos aprender es el prop drilling, que básicamente es pasar el estado por nuestros componentes mediante las props de estos.
A continuación veamos un ejemplo básico.
import React, { useState } from 'react'
export const App = () => {
const [product, setProduct] = useState({
name: 'TV Samsumg',
price: 1499.99,
img: 'https://images.samsung.com/is/image/samsung/mx-full-hd-t5300-un43t5300afxzx-frontblack-234815390?$720_576_PNG$'
})
return (
<React.Fragment><h1>Mi Tienda 😎</h1><ProductContainerimg={product.img}name={product.name}price={product.price}
/></React.Fragment>
)
}
const ProductContainer = ({img, name, price}) => {
return (
<div>
<img src={img} alt="image" />
<ProductDataname={name}price={price} /></div>
)
}
const ProductData = ({name, price}) => {
return (
<div>
<h2>{name}</h2><p>$ {price}</p></div>
)
}
Como se observa, realmente el componente ProductContainer no realiza nada con las props name y price, solamente las manda al siguiente componente (ProductData).
Peeeero y si por alguna razón nuestro componente ProductData cambia y ahora ya no recibe name y price en las props, solamente un objeto llamado data. 🧐🤔
import React, { useState } from 'react'
export const App = () => {
const [product, setProduct] = useState({
name: 'TV Samsumg',
price: 1499.99,
img: 'https://images.samsung.com/is/image/samsung/mx-full-hd-t5300-un43t5300afxzx-frontblack-234815390?$720_576_PNG$'
})
return (
<React.Fragment><h1>Mi Tienda 😎</h1><ProductContainerimg={product.img}data={{name: product.name, price: product.price}}
/></React.Fragment>
)
}
const ProductContainer = ({img, data}) => {
return (
<div>
<img src={img} alt="image" />
<ProductDatadata={data} /></div>
)
}
const ProductData = ({data}) => {
return (
<div>
<h2>{data.name}</h2><p>$ {data.price}</p></div>
)
}
Como se observa tuvimos que modificar dos componentes (A esto se le suele conocer como acoplamiento de componentes), ProductContainer y ProductData, en este caso no es complicado realizar la modificación pues solo fue en dos componentes, pero piense en el caso de que las props pasan por diferentes componentes hijos, ya no sería hacer el cambio en dos componentes, serían muchos mas y eso es aburrido, tedioso y pueden haber fallos, que si no pase bien la prop. 🥲
Si nuestro código crece y tenemos mas componentes hijos, a la larga es poco mantenible, ¿cómo solucionamos este acoplamiento? 😰
Obviamente ya todos tomamos el curso de introducción a React.js, si no, te recomiendo que lo hagas, te dejo el link aqui
Entonces claramente podemos usar el context que nos proporciona react. GRACIAS REACT 😮💨
import React, { createContext, useState } from 'react'
const ProductContext = createContext({});
export const App = () => {
const [product, setProduct] = useState({
name: 'TV Samsumg',
price: 1499.99,
img: 'https://images.samsung.com/is/image/samsung/mx-full-hd-t5300-un43t5300afxzx-frontblack-234815390?$720_576_PNG$'
})
return (
<React.Fragment><h1>Mi Tienda 😎</h1><ProductContext.Providervalue={{name:product.name, price:product.price}} ><ProductContainerimg={product.img}
/></ProductContext.Provider></React.Fragment>
)
}
const ProductContainer = ({img}) => {
return (
<div><imgsrc={img}alt="image" /><ProductData /></div>
)
}
const ProductData = () => {
return (
<ProductContext.Consumer>
{
(data) => (
<div><h2>{data.name}</h2><p>$ {data.price}</p></div>
)
}
</ProductContext.Consumer>
)
}
MAGIAAAAA!!!
Quitamos esa dependencia que existia entre ProductContainer y ProductData, ahora podemos modificar cuanto queramos nuestro producto que ya no afectara a ProductContainer.
Nos vamos todos ya, el problema ha sido solucionado, FIN. 😁
¿Qué?, ¿No ha acabado? 😫
Por supuesto que no.
No esta mal usar el context, pero muchas veces ¿Es necesario? 🤔
¿Qué pasaría si tuvieramos una buena composición de componentes? 🤔
¿Existiria el acoplamiento? 🤔
¿Propdrilling? 🤔
NOOOOO, haciendo uso de la composición de componentes nos podemos deshacer del context.
Adios context.
Hola composición de componentes. 🥰
Veamos como quedaría nuestro código.
import React, { Children, useState } from "react";
export const App = () => {
const [product, setProduct] = useState({
name:"TV Samsumg",
price:1499.99,
img:"https://images.samsung.com/is/image/samsung/mx-full-hd-t5300-un43t5300afxzx-frontblack-234815390?$720_576_PNG$"
});
return (
<React.Fragment><h1>Mi Tienda 😎</h1><ProductContainer img={product.img}><ProductData data={{ name: product.name, price: product.price }} /></ProductContainer></React.Fragment>
);
};
const ProductContainer = ({ img, children}) => {
return (
<div><img src={img} alt="image" />
{children}
</div>
);
};
const ProductData = ({ data }) => {
return (
<div><h2>{data.name}</h2><p>$ {data.price}</p></div>
);
};
Y TADAAAAAAN, el mago lo hizo de nuevo, nuestros componentes también quedaron desacoplados.
Como conclusión me gustaría añadir que debemos tomar en muy en cuenta como vamos a manejar nuestro estado en la aplicación, muchas veces va a ser tan sencilla que con el prop drilling es suficiente o un poco compleja que sea necesario el context, pero antes de usar el context, hagámonos la pregunta ¿Es necesario?, ¿Una buena composición de componentes podría ser suficiente? 🤔
¿Qué pasaría si nuestra aplicación es algo grande y compleja que el context que nos proporciona react ya no es suficiente? Por suerte existen diferentes herramientas que nos ayudan a manejar el estado de nuestra aplicación, como lo es redux!
Desde aquí doy la iniciativa a que sea actualizado el curso de redux que hay en la plataforma, espero lo tomen en cuenta. 😘
Sin mas, los dejo, espero les haya gustado mi primer post/tutorial/como lo quieran llamar, y como todos, soy una persona que sigue aprendiendo y no lo sabe todo, si tienen algún comentario u observación, háganlo saber!
#NuncaParesDeAprender🚀
excelente explicacion mi amigo! 💪
Buenaso el aporte, gracias 😄
Buenaso el aporte, gracias 😄