React: 4 tipos de componentes para gobernarlos a todos

Descubre los distintos componentes que puedes definir en React

Image for post
Image for post

Si ya has trabajado con React en algún proyecto probablemente te habrás encontrado con términos como “dumb components”, “stateless components” o “high order components” los cuales sirven para describir distintas formas de definir y crear componentes en nuestra aplicación.

La idea de este artículo es explicar los distintos tipos de componentes que podemos crear en React y la forma en que podemos emplearlos de cara a que nuestro código sea más fácil de entender y mantenible.

Cuando creamos un proyecto en React mediante la instrucción create-react-app partiremos de un componente base en el cual se agrupan diferentes funcionalidades y características como la función render , las props , su propio state o los lifecycle events o su propio contexto:

Image for post
Image for post
https://www.youtube.com/watch?v=YaZg8wg39QQ

Sin embargo, los componentes que habitualmente emplearemos tan solo emplearán una parte de todas esas API’s; de hecho, podemos separarlos en dos grandes grupos:

  • Aquellos componentes que emplean la función render junto con las props y el context asociado
  • Los componentes que emplean la función render, el state y los lifecycle events

Es a partir de este punto en el que surgen los dos primeros tipos de componentes.

Este tipo de componentes, probablemente el más básico que podemos definir, y que también es conocido como stateless components, se encarga tan solo de pintar los elementos en base a las props recibidas por los otros componentes donde aparezcan embebidos. De ahí que también reciban el sobrenombre de stateless ya que ellos mismos no almacenan ningún tipo de estado, limitándose a presentar los datos por pantalla. De hecho, a menudo los definiremos directamente como funciones que devuelven el HTML correspondiente sin necesidad de extender la clase React.Component

La ventaja más evidente de separar estos componentes del resto es la posibilidad de reutilizarlos siempre que queramos sin tener que recurrir a escribir el mismo código una y otra vez

Ejemplo:

const Box = props => <div>{props.name}</div>

Por otra parte, los container components son aquellos componentes que sí emplean la API state para establecer la lógica y el funcionamiento de nuestra aplicación, de ahí que también sean conocidos como state components.

Este tipo de componentes, por tanto, serán los encargados de realizar llamadas a las API’s externas, conectarse a Redux o establecer la lógica a realizar en función de las acciones que realice el usuario sobre la interfaz.

Por ejemplo:

class ContainerBox {
constructor() {
super();
this.state = { name: "Gerardo" }
}
render() {
return <Box {...state} />
}
}

Como veis, el anterior componente Box podemos reutilizarlo donde queramos, de modo que resulta muy sencillo reutilizar código mientras que delegamos la lógica a los contenedores.

Sin embargo, ¿cómo podríamos conseguir reutilizar también nuestro componente ContainerBox` del mismo modo en que hemos hecho con el componente Box ? Es aquí donde entra el tercer tipo de componente (o patrón) que podemos emplear.

Cuando hablamos en React de high order components, hablamos de componentes que reciben como parámetro un componente y devuelven un nuevo componente, habitualmente encapsulando el componente recibido con funcionalidad adicional. De hecho, este patrón es el que se emplea en la librería react-redux cuando creamos un componente mediante la instrucción connect(MyComponent) .

Emplear este patrón puede ser al principio confuso pero en el momento en que comenzamos a sentirnos a gusto con él es uno de los más poderosos que podemos emplear en el diseño de nuestra aplicación.

Volviendo a nuestro ejemplo, para definir un high order component sobre nuestro ContainerBox podríamos escribir el siguiente código:

function ContainerBoxHoc(AnyBox) {
return class ContainerBox extends React.Component {
constructor() {
super();
this.state = { name: “Gerardo” }
}
render() {
return <AnyBox {…this.state} />
}
}
}
const ContainerBox = ContainerBoxHoc(Box);function SpanBox = props => <span>{props.name}</span>
const OtherContainerBox = ContainerBoxHoc(SpanBox)

Como veis, podemos crear tantos ContainerBox como queramos y cada uno de ellos podrá pintar el tipo de Box que necesitemos. Lógicamente este es un ejemplo muy sencillo, pero si navegáis por la documentación oficial encontraréis otros algo más complejos donde podréis comprobar las ventajas de los high ordered components.

Finalmente, el último tipo de componente o patrón (yo prefiero en este caso emplear este último término) que podemos emplear a la hora de definir la estructura de nuestra aplicación es el que se conoce como render props.

La característica de este tipo de componentes es que reciben una función a través de las props (la cual devuelve un elemento de React) y que será la que empleen dentro de su propia función render para pintar por pantalla. Por ejemplo, nuestro componente ContainerBox podríamos definirlo del siguiente modo:

class ContainerBox extends React.Component {
constructor() {
super();
this.state = { name: “Gerardo” }
}
render() {
return this.props.renderBox(this.state);
}
}
const Box = props => <div>{props.name}</div>const ContainerBoxWithBox = (
<ContainerBox renderBox={state => (<Box {…state} />)} />
);

Como veis en este caso es una función externa al componente la que establece lo que se pinta y cómo se pinta limitándose el componente ContainerBox a establecer el resto de la lógica y emplear esta propiedad como valor de retorno de su propia función render .

Conociendo estos 4 tipos de componentes (o patrones) podréis plantear la estructura de vuestra aplicación en un modo que os permitirá tanto reutilizar multitud componentes como conseguir que el código sea mucho más mantenible, algo que en aplicaciones de gran tamaño es de agredecer.

Si os interesa conocer más sobre los distintos de componentes os recomiendo las siguientes charlas:

¿Quieres recibir más artículos como este?

Suscríbete a nuestra newsletter:

Written by

Entre paseo y paseo con Simba desarrollo en Symfony y React

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store