Cómo desarrollar tus superpoderes React con el patrón HOC

¡Hola a todos! ? ¡Espero que hayan tenido una Feliz, Feliz Navidad y un Próspero Año Nuevo!

¡2018 ha llegado a su fin y tiene sentido para mí comenzar el nuevo año con un artículo sobre Componentes de orden superior!

Te prometí que escribirías sobre ello ya que abordamos el tema cuando hablamos de los accesorios de renderizado y los patrones de los contenedores, así que tiene sentido profundizar un poco y prestarle atención.

Personalmente, no es uno de mis patrones favoritos, pero es una herramienta poderosa para conocer, dominar y colgar de su cinturón de herramientas.

Solo tenga en cuenta que no debe abusar de él. Casi todo lo que puede encapsular en un HOC ciertamente puede implementar utilizando el patrón de accesorios de renderizado (consulte mi artículo sobre accesorios de renderizado aquí) y viceversa.

01. ¿Qué es un componente de orden superior?

Un componente de orden superior (HOC) es una técnica avanzada en React para reutilizar la lógica del componente. Los HOC no forman parte de la API de React. Son un patrón que se deriva de la naturaleza de React que privilegia la composición sobre la herencia.

JavaScript es un lenguaje adecuado para la programación funcional, ya que puede aceptar funciones de orden superior. Una función de orden superior es una función que puede tomar otra función como argumento y / o que devuelve una función como resultado.

De la misma manera, un componente de orden superior es una función que toma (envuelve) un componente y devuelve un nuevo componente .

Las funciones de orden superior nos permiten abstraer acciones, no solo valores.

Los HOC son comunes en las librerías React de terceros, como Redux o React Router. Apuesto a que ha usado algunos de ellos, tal vez sin darse cuenta.

El propósito principal de un componente de orden superior en React es compartir una funcionalidad común entre componentes sin repetir código.

02. Tipos de componentes de orden superior

Básicamente, hay dos tipos principales de implementación de HOC: Props Proxy e Inheritance Inversion .

Props Proxy (ppHOC)

Props Proxy HOC se expresan de forma elemental así:

No es más que una función, propsProxyHOC, que recibe un Componente como argumento (en este caso llamamos al argumento WrappedComponent) y devuelve un nuevo componente con el WrappedComponent dentro.

Tenga en cuenta que cuando devolvemos el WrappedComponent, también pasamos por los accesorios que recibe el HOC. Esto explica el nombre dado a este tipo: props proxy .

Cuando devolvemos el componente envuelto, tenemos la posibilidad de manipular accesorios y abstraer el estado, incluso pasando el estado como accesorio al componente envuelto.

También puede envolver el componente envuelto con otros elementos JSX cambiando su interfaz de usuario según las necesidades de su aplicación.

Props Proxy HOCs son útiles para las siguientes situaciones:

  1. Manipulación de accesorios
  2. Accediendo a la instancia a través de Refs (tenga cuidado, evite usar refs)
  3. Estado abstracto
  4. Envolver / componer el WrappedComponent con otros elementos

Inversión de herencia (iiHOC)

Los HOC de herencia invertida se expresan de manera elemental así:

En esta situación, la clase devuelta amplía el WrappedComponent. Se llama Inheritance Inversion, porque en lugar de que WrappedComponent extienda alguna clase Enhancer, se extiende pasivamente. De esta forma la relación entre ellos parece inversa .

La inversión de herencia le da al HOC acceso a la instancia de WrappedComponent a través de esto , lo que significa que puede usar el estado, los accesorios, el ciclo de vida del componente e incluso el método de representación .

Los HOC de herencia de inversión son útiles para las siguientes situaciones:

  1. Hacer Highjacking
  2. Estado de manipulación

03. Ensuciarnos las manos

¿De acuerdo todos? Para ilustrar un poco los conceptos presentados anteriormente, hagamos algo de código.

Si quieres jugar más tarde con el código que estamos haciendo, ¿puedes sacarlo de este repositorio mío ?.

Intentemos implementar un componente que devuelva un mensaje de bienvenida de acuerdo con el usuario que está conectado al sistema.

Modifiqué mi componente App.js para mostrar algo de texto y renderizar un componente llamado Bienvenido al que paso el usuario prop.

Ok, podemos hacer eso con un componente simple como este:

Pero…

¿Qué sucede si quiero que el componente devuelva Bienvenido invitado si no hay ningún usuario conectado?

Bueno… puedo hacer eso en el mismo componente de Bienvenida, con un simple if que verifica si existe el prop del usuario y si no, simplemente devuelve “Welcome Guest”.

Pero supongamos que quiero encapsular esa lógica para usar con múltiples / diferentes Componentes de Bienvenida.

Entonces, el camino a seguir es hacer un Props Proxy HOC:

¿Qué hemos hecho aquí? Mantuvimos nuestro componente de bienvenida simple y hemos creado una función de JavaScript llamada withUser que obtiene el componente de bienvenida (WrappedComponent) como argumento y verifica si existe el usuario prop. Si no es así, simplemente devuelve un simple "¡Bienvenido invitado!" mensaje.

Esto es muy útil. Imagine que tiene 30 componentes de bienvenida en diferentes idiomas (ejemplo tonto, pero tiene el objetivo de encapsular la lógica en un HOC).

Bien, ahora tenemos un HOC para verificar si hay un usuario conectado, de lo contrario, lanza un mensaje de bienvenida como invitado.

Imaginemos ahora que la información del usuario proviene de una API externa (Auth0, por ejemplo) y está ingresando a nuestra aplicación frontend a través de un reductor Redux que administra el estado de la aplicación.

Entonces, antes de verificar si hay un usuario, ¡debemos verificar si los datos están cargados en el sistema!

¡Guauu! ¡De esta manera podríamos mostrar un mensaje de carga mientras no se cargan los datos!

Entonces ... para este caso de uso, supongo que queremos hacer un render highjacking y renderizar otra cosa si los datos no están cargados.

Para renderizar highjacking necesitamos usar un iiHOC. ¡Guauu! ¡Qué coincidencia! Entonces, ¿hagámoslo y compongamos los dos HOC juntos? Esto golpeará con fuerza la cabeza de la uña.

Preste atención a lo que hemos hecho:

Hemos creado un withLoader iiHOC que amplía el WrappedComponent. De esta manera, puede acceder a sus accesorios y activar diferentes renderizados.

En esta situación, obtenemos el prop isLoaded y si no está cargado, ¡simplemente devolvemos un mensaje de carga! De lo contrario, dejamos que WrappedComponent se procese simplemente devolviendo super.render ().

En la declaración de exportación, solo estamos componiendo dos funciones de JavaScript como f1 (f2 (f3))). ¡Nada más que eso!

Hay herramientas para componer funciones de una manera más bonita, ¡pero esa es otra historia para otro artículo!

04. Por último, pero no menos importante

He intentado utilizar ejemplos sencillos para que pueda comprender los conceptos de la forma más limpia posible.

Mi consejo para ti es que si no dominas estos conceptos, por favor tira de mi repositorio aquí y juega un poco con él.

Verifique el código e intente entenderlo línea por línea.

Se necesita algo de tiempo para acostumbrarse y sentirse cómodo haciendo este tipo de abstracción, así que no pierda su motivación o su enfoque con los HOC.

Además, como dije antes, todo lo que hemos hecho aquí se puede lograr con accesorios de renderizado o patrón de contenedor, por lo que no es obligatorio elegir uno o dos HOC para hacer código limpio con este tipo de encapsulación.

¡Espero que te hayas divertido tanto leyendo este artículo como yo escribiéndolo! Si realmente te gustó, dame algunas palmas (no menos de 50 por favor). y recuerde siempre "¡Sea fuerte y codifique!"

Además, si desea explicaciones más profundas y complejas, no dude en leer los enlaces que agregué a la sección Bibliografía a continuación.

05. Bibliografía

  1. Reaccionar la documentación

2. Javascript elocuente

3. Reaccionar componentes de orden superior en profundidad

¡Muchas gracias!

evedes, dic 2018