Gestionando temas con Custom Hooks, React Context API y TypeScript en una aplicación React Native
Luísa Barros. React Native es un framework de JavaScript utilizado principalmente para construir aplicaciones multiplataforma para dispositivos móviles. El desarrollo de interfaces que capturen la atención del usuario involucra muchas variables, y una de ellas es el conjunto de estilos que compondrán dicha interfaz.
En este artículo, detallaremos la importancia de una buena gestión de estilos a través de temas, aprovechando al máximo TypeScript, React Hooks, Context API y Styled Components.
Los temas nos permiten estandarizar y reutilizar estilos en varios componentes de la aplicación, y no son más que simples objetos donde definimos colores, tipografía, tamaños, espaciados y diversas otras propiedades que constituyen la interfaz de usuario (UI) de nuestra aplicación. Las posibilidades de uso de los temas están orientadas a:
- mantener la consistencia de la identidad de marca de la aplicación;
- facilitar la implementación de funcionalidades como los modos claro y oscuro;
- personalizar la aplicación según las preferencias del usuario;
- mejorar la accesibilidad (tamaño de fuentes, corrección de colores, etc.);
Entonces, en lugar de, por ejemplo, pasar el código hexadecimal de un color directamente al componente, lo haríamos a través de un tema:
El ejemplo anterior puede no aclarar completamente la razón del uso de temas, ya que parece generar código adicional para un solo uso. Sin embargo, imagina una situación en la que trabajamos con una aplicación que tiene una gran cantidad de componentes y necesitamos cambiar el color de todos los textos del sistema. En este caso, en lugar de modificar cada componente individualmente, podríamos simplemente ajustar el tema.
Creando los objetos de tema
Inicialmente, mantendremos toda la lógica en un solo archivo, pero, conforme el proyecto escale, podría ser conveniente crear una carpeta específica para definir las propiedades de cada objeto de tema. Antes de eso, determinaremos el tipado del objeto, de modo que cada uno tenga los mismos atributos y no haya discrepancias. Aquí es donde entra en juego la gran estrella: TypeScript. Crearemos entonces un tipo llamado Theme:
Nota: Las tres propiedades siguientes son solo un ejemplo; puedes crear las tuyas propias. Si usas alguna biblioteca con componentes ya predefinidos como Native Base, Material UI o React Native Paper, es importante identificar en la documentación la especificación que siguen y crear tu objeto de temas en el mismo formato. Así, puedes realizar las personalizaciones necesarias extendiendo el Tema Predeterminado de la biblioteca o pasar directamente el objeto con tus propiedades.
Para garantizar la libertad de añadir cuantos temas queramos, crearemos un único objeto que contendrá todos los temas. Será del tipo Record<Theme['mode'], Theme>, con claves y valores de un tipo específico. En el ejemplo siguiente, la clave será del tipo 'LIGHT' | 'DARK' y el valor será del tipo Theme, que creamos anteriormente:
Con el objeto de tema creado, podemos avanzar a los siguientes pasos: gestionar la funcionalidad de cambio de temas y dejarlo disponible en toda la aplicación
Creando un hook personalizado: `useTheme`
Muchas bibliotecas tienen soporte para temas, lo que nos permite gestionarlos de forma más práctica. Dependiendo de la complejidad de la aplicación y del acoplamiento con bibliotecas de terceros, puede ser conveniente utilizar los recursos que estas exportan, ya que requieren mínimas configuraciones para implementarse. Sin embargo, ¡crearemos nuestro propio hook personalizado! Esto nos garantiza un control total de la estructura, encapsulando la lógica de gestión de temas en un solo lugar, además de no depender de ninguna biblioteca externa.
Un hook personalizado no es más que una función que utiliza las funcionalidades de estado y ciclo de vida de React, permitiéndonos crear fragmentos de código que pueden compartirse fácilmente entre varios componentes. Necesita tener el prefijo 'use' + un nombre que comience con letra mayúscula (por ejemplo, useTheme). Nuestro hook devolverá una función llamada switchTheme, que cambiará el tema actual, y currentTheme - un estado con el objeto del tema que se está utilizando en el momento.
Disponibilizando el `useTheme` con la Context API
Con el hook creado, necesitamos hacerlo accesible desde cualquier lugar de la aplicación. Para esto, usaremos la API de contexto nativa de React, con el fin de hacer disponible globalmente el objeto de tema y la función de cambio, que son exportados por el hook. Primero, crearemos el contexto y utilizaremos useContext() en nuestro hook personalizado:
Si prestaste atención al código anterior, notaste que lanzamos un error si el contexto no está definido, exigiendo que el hook sea usado dentro de un ThemeProvider. Esta es la forma en que React gestiona el acceso a los contextos, y es justamente el Provider quien asocia un contexto a un determinado alcance. Ahora exportaremos nuestro Provider:
¡Listo! Todo está preparado para que podamos usar nuestro tema en la aplicación.
Utilizando el `useTheme` 🎉
Finalmente, podemos acceder a las funcionalidades proporcionadas por nuestro hook personalizado en cualquier componente funcional del sistema. Para ello, solo necesitamos importarlo e invocarlo:
En el ejemplo anterior, utilizamos estilos en línea, pero Styled Components nos permite crear componentes personalizados usando una sintaxis muy similar a la utilizada en la web, CSS-in-JS. Si estuviéramos usando el Provider de la biblioteca, podríamos simplemente extender la interfaz DefaultTheme de esta:
Sin embargo, dado que creamos nuestro propio hook, necesitamos pasarlo mediante props. De esta forma, podemos acceder a nuestro tema en los archivos de estilización y aprovechar TypeScript a nuestro favor:
Conclusión
En este artículo, exploramos la importancia de los temas en aplicaciones móviles y cómo pueden mejorar la experiencia del usuario. Desarrollamos un hook personalizado que permite un control centralizado de los estilos, priorizando código limpio y reutilizable. Hicimos que este hook esté disponible globalmente en la aplicación con la Context API de React, mediante un Provider, permitiendo que sea consumido tanto por componentes funcionales como por archivos de estilización. Por último, vimos cómo TypeScript jugó un papel fundamental para definir estructuras de datos sólidas, asegurando la cohesión de atributos y propiedades en toda la aplicación. Espero que, con estas herramientas, estés más capacitado para crear aplicaciones con interfaces visualmente consistentes y altamente personalizables.
Referencias
https://reactnavigation.org/docs/themes
https://styled-components.com/docs/advanced#theming
https://react.dev/learn/passing-data-deeply-with-context
Listopro Community da la bienvenida a todas las razas, etnias, nacionalidades, credos, géneros, orientaciones, puntos de vista e ideologías, siempre y cuando promuevan la diversidad, la equidad, la inclusión y el crecimiento profesional de los profesionales en tecnología.