DEV Community

Cover image for React la guía máxima de buenas prácticas jamás concebida, Principios SOLID, El acrónimo STUPID, Clean Code y Code Smell
Dennys José Márquez Reyes
Dennys José Márquez Reyes

Posted on • Updated on

React la guía máxima de buenas prácticas jamás concebida, Principios SOLID, El acrónimo STUPID, Clean Code y Code Smell

Ingeniería de software.

Como desarrollador, estoy constantemente pensando en cómo hacer mi código más eficiente y mantenible, les comparto los principios SOLID aplicados a React, Clean Code, el acrónimo STUPID y algunos Code Smell.

Los principios SOLID y el Código Limpio son dos conceptos importantes con los que todo desarrollador debería estar familiarizado.

Veamos cómo estos conceptos se pueden aplicar a React, y también vamos a discutir algunos de los Code Smells más comunes en React.

SOLID es un acrónimo de cinco principios de diseño que fueron introducidos por primera vez por Robert C. Martin en su libro “Agile Software Development, Principles, Patterns, and Practices”.

Una de las principales ventajas de React es su arquitectura basada en componentes, esto significa que una aplicación se compone de piezas pequeñas y reutilizables que se pueden mantener y ampliar fácilmente.

Siguiendo los principios SOLID, puedes mejorar aún más la estructura de tu código y hacer que sea aún más fácil trabajar con él.

El acrónimo significa:

\

  • Principio de Responsabilidad Única (SRP).
  • Principio de Apertura-Cierre (OCP).
  • Principio de Sustitución de Liskov (LSP).
  • Principio de Segregación de Interfaces (ISP).
  • Principio de Inversión de Dependencias (DIP).

\

Principio de Responsabilidad Única (SRP).

Este principio establece que un módulo o clase debe de tener una sola responsabilidad, cada módulo de software debe tener responsabilidad sobre una sola parte de la funcionalidad proporcionada por la aplicación.

Seguir el principio SRP tiene varias ventajas.

En primer lugar: Facilita la comprensión y el mantenimiento del código porque cada módulo o clase tiene un propósito bien definido.

En segundo lugar: Aumenta la reutilización del código porque los módulos pueden reutilizarse en otras partes de la aplicación donde encajen.

En otras palabras, cada módulo o componente debe hacer una sola cosa y hacerla bien.

Esto ayuda a mantener el software limpio y fácil de mantener, ya que es más fácil comprender qué está pasando si todo está dividido en pequeñas partes con funciones claramente definidas.

Aplicar el principio SRP en React significa dividir los componentes en pequeños pedazos que sean lo suficientemente simples como para ser entendidos fácilmente y no tengan demasiadas responsabilidades.

De esta forma, si algo sale mal, es mucho más fácil identificar el problema y arreglarlo sin tener que rastrear todo el código para encontrar dónde podría estar el error.

Todos los componentes deben tener un solo propósito, si tienes un componente para mostrar datos y otro componente para manipularlos, entonces tendría sentido separarlos en dos componentes diferentes.

De esta forma, el primer componente se encargaría solo de mostrar los datos y el segundo componente se encargaría solo de manipularlos, esto ayudaría a mantener el código relativamente limpio y simple.

El SRP es a menudo citado como el principio más importante en la POO, y definitivamente vale la pena seguirlo en tus aplicaciones React.

Por supuesto, como todos los principios, siempre hay espacio para la interpretación y el debate sobre si algo viola o no la SRP.

Mientras tengan en mente el objetivo general de mantener los módulos u clases centradas en áreas únicas de responsabilidad, estarán en el camino correcto hacia la creación código limpio y mantenibles.

REF: es.wikipedia.org

\

Algunos ejemplos de cómo pueden aplicar el SRP en los componentes de React:

\

1.

Si un componente necesita hacer una llamada Ajax para obtener datos de una API, entonces necesitaría depender de algo como Axios.

Pero si el mismo componente también necesita acceder al almacenamiento local, entonces depender de algo como localStorage no sería necesario y podría conducir a un acoplamiento innecesario entre los componentes.

Así que en este caso, adherirse al SRP significaría evitar dependencias innecesarias.

Un componente solo debe tener dependencias directas de cosas que sean necesarias para su única responsabilidad.

2.

Un componente que renderiza un formulario no debería ser también responsable de manejar el envío del mismo.

Son dos responsabilidades diferentes y, por lo tanto, violaría la SRP.

Un componente solo debe tener un trabajo o responsabilidad.

3.

Si dos componentes necesitan acceder a la misma parte de un estado, entonces ambos se acoplan y los cambios en uno probablemente acabarán afectando al otro.

Esto viola el espíritu de la encapsulación, que está en el corazón de este buen principio.

Los componentes no deberían compartir el estado entre ellos a menos que sea absolutamente necesario.

4.

Cuando se construyen aplicaciones grandes con muchas piezas pequeñas, se puede intentar crear lo que algunas personas denominan componentes «dios», que son enormes componentes envolventes que intentan hacerlo todo y acaban teniendo 2.000 líneas de longitud.

Esto no solo hace que tu código sea más difícil de mantener, sino que va en contra de todo lo que hace grande a React — ¡pequeñas unidades modulares componibles!

Evite los componentes «dios».

5.

Una forma de aumentar el nivel de abstracción cuando se piensa en los componentes individuales de React es si son de presentación o de contenedor.

Los componentes de presentación tienden a no preocuparse demasiado por la lógica de la aplicación, se centran en el aspecto de las cosas (HTML/CSS).

Los componentes contenedores, sin embargo, se centran principalmente en proporcionar datos y comportamiento a los componentes de presentación (hijos) que se encuentran por debajo en la jerarquía.

Mantenga sus componentes de presentación y de contenedor separados

6.

Los HOCs son una gran herramienta proporcionada por React para abstraer la funcionalidad común.

Esto nos permite crear componentes reutilizables que se pueden utilizar en varios lugares de nuestra aplicación, también ayuda a mantener nuestro código limpio y organizado, ya que podemos separar la lógica del componente de su representación visual.

Utilizar Componentes de Orden Superior cuando sea apropiado

7.

El SRP también puede aplicarse a nivel de props individuales y variables de estado, cada prop o variable de estado debe ser utilizada sólo para su propósito; si necesita ser cambiada por cualquier otra razón, debe ser extraída en su propia prop o variable de estado.

8.

Sigan las mejores prácticas a la hora de nombrar componentes, utilicen nombres claros que describan su propósito único (por ejemplo, AvatarComponent), esto evitara que se le asignen responsabilidades de más a un componente, e igual aplica para el nombrado de las clases.

9.

Una forma común de violar el SRP es crear componentes «wrapper» que realmente no añaden ningún valor ni sirven para nada más que para envolver otro componente.

const MyComponent = ({ name }) => name;
Enter fullscreen mode Exit fullscreen mode

👆 En este caso este componente no hace realmente nada más que devolver una prop, una mejor manera de escribir esto sería simplemente devolver la prop directamente.

const MyComponent = ({ name }) => (<div>{name}</div>);
Enter fullscreen mode Exit fullscreen mode

👆

Otra forma común de violar el SRP es creando componentes “contenedores” que son responsables tanto de la obtención de datos como de la presentación de la interfaz de usuario. Una mejor manera de manejar esto sería crear un componente contenedor separado para la obtención de datos y un componente de presentación para la representación de la interfaz de usuario.

Utilizar el principio SRP ayuda a crear software mejor organizado y menos propenso a errores, lo que facilita la escalabilidad del mismo.

REF: SRP de 7 principios para un diseño confiable de componentes React - programador clic


Principio de Apertura-Cierre (OCP)

Establece que un componente de software debe estar abierto a la ampliación, pero cerrado a la modificación, esto significa que un componente debe diseñarse de forma que pueda ampliarse sin tener que modificar el código existente, la ventaja de este enfoque es que permite añadir nuevas características sin afectar a la funcionalidad existente.

Una de las ventajas de React es que utiliza un modelo de programación declarativo que facilita la ampliación y adición de nuevas funciones, si quieres añadir un nuevo botón a tu aplicación, puedes simplemente crear un nuevo componente e incluirlo en tu código sin tener que modificar ningún componente existente.

Este principio ayuda a que React sea más flexible y extensible, lo que lo convierte en una opción ideal para el desarrollo web moderno.

Las ventajas de seguir el OCP son una menor complejidad y una mayor flexibilidad, al no tener que modificar el código existente, hay menos posibilidades de introducir errores en el código que funciona, además, si se sigue este principio , se pueden añadir nuevas funcionalidades con mayor facilidad y rapidez.

\

Hay muchas maneras de lograr el OCP en React, algunos ejemplos:

\

1.

Utilizar componentes de orden superior (HOC) para ampliar la funcionalidad del componente sin modificar el propio componente.

2.

Crear componentes reutilizables que puedan ser usados en diferentes partes de tu aplicación sin necesidad de hacer cambios cada vez que se usen.

3Escribir código bien factorizado para que sea más fácil añadir nuevas características o refactorizar las existentes sin romper cosas involuntariamente.

4.

Utilizar objetos de configuración para almacenar datos que puedan cambiar sin necesidad de modificar el código.

5.

Implementa un sistema de eventos para que las diferentes partes de tu aplicación puedan comunicarse entre sí sin acoplarse estrechamente.

6.

Utilizar la inyección de dependencias para desacoplar los componentes entre sí y facilitar su comprobación de forma aislada.

7.

Evite el uso de estado global, o si debe usarlo, utilice una biblioteca como Redux que proporciona una forma bien definida de acceder y actualizar el estado global de forma segura.

8.

Sigue el principio de la menor sorpresa: asegúrate de que tu código se comporta de forma coherente con las expectativas y que sea fácil de entender.


Principio de Sustitución de Liskov (LSP)

Establece que los objetos de un programa deben sustituirse por instancias de sus subtipos sin que ello afecte a la corrección del programa.

El principio de Liskov establece que una subclase debe ser capaz de ser utilizada en lugar de su clase base sin afectar el comportamiento del programa.

👉Esto significa que la subclase puede agregar nuevos métodos o comportamientos, pero no debe eliminar anular o cambiar los métodos de la clase base para cumplir con el principio de Sustitución de Liskov.

El principio de Liskov nos brinda una guía para utilizar la herencia de manera adecuada y para ser cuidadosos al extender de otras clases. La herencia puede dar lugar a una jerarquía de clases compleja y difícil de mantener.

La idea general es que si S es un subtipo (o clase hija) de T (clase madre), entonces un objeto del tipo T puede ser sustituido por un objeto de tipo S.

En React, este principio se puede aplicar a los props, al estado y a los componentes, si tienes un componente que muestra un campo de entrada, puedes sustituirlo por otro componente que también muestre un campo de entrada sin afectar a la funcionalidad general de tu aplicación.

Lo mismo ocurriría si sustituyera una variable de estado o prop por otra instancia de su tipo, sin embargo, si se reemplaza una variable prop o de estado con una de otro tipo completamente diferente (como reemplazar un array prop con un objeto), entonces esto podría romper potencialmente su aplicación.

TypeScript es particularmente adecuado para aplicar el principio de sustitución de Liskov debido a su sistema de tipado estático.

Esto significa que una vez que se definen los tipos para las variables de estado y los props, es mucho más difícil (si no imposible) sustituirlos accidentalmente por valores de otros tipos.

En sustitución de TypeScript se deben de usar los PropTypes.

\

Ejemplos de cómo se puede aplicar el principio de sustitución de Liskov en React:

\

1.

Props: Cuando definas props para un componente, utiliza siempre el tipo más específico posible.

Si tienes un prop opcional que puede ser una cadena o un array, defínelo como un array: myPropType = PropTypes.arrayOf(PropTypes.string).

Esto evitará que se produzcan errores al intentar pasar tipos de datos no válidos a su componente en el futuro.

2.

TypeScript: Utiliza TypeScript en lugar de JavaScript siempre que sea posible cuando trabajes en proyectos React .

Esto no solo proporciona una mejor seguridad de Types, también obtendrán un mejor soporte en sus IDE, también tendrán características de autocompletado.

3.

Prop Types: Utilice siempre la validación de Prop Types cuando creen componentes.

Esto asegurará que se está pasando props válidas a un componente, lo cual evita los errores que pueden ocurren más adelante.


Principio de Segregación de Interfaces (ISP)

Es un principio del diseño orientado a objetos que dice que ningún módulos, clases, o componentes, entre otros debe ser forzado a depender de métodos que no utiliza, en otras palabras, cada clase debe tener su propia interfaz bien definida y específica.

interface name {
  firstName: string;
  lastName: string;
  getFullName(): string;
}
Enter fullscreen mode Exit fullscreen mode

👉 En el diseño de interfaces, se debe tener en cuenta la responsabilidad única y la cohesión. Cada interfaz debe tener una única responsabilidad y estar diseñada para cumplir con esa responsabilidad específica. Además, el nombre de la interfaz debe reflejar claramente su propósito y las funcionalidades que ofrece.

Una interfaz no debe tener responsabilidades mixtas o agregar propiedades y métodos que no están relacionados con su propósito original solo para satisfacer las necesidades de otros módulos, clases o componentes.

interface name {
  firstName: string;
  lastName: string;
  getFullName(): string;
  age: number; // propiedad no relacionada
  getAddress(): string; // método no relacionado
}
Enter fullscreen mode Exit fullscreen mode

ISP está estrechamente relacionado con el principio de responsabilidad única (SRP), de hecho, son dos caras de la misma moneda, el SRP se ocupa de las clases y el ISP de las interfaces, una interfaz es como una clase, pero en lugar de contener detalles de implementación, solo contiene firmas de métodos (es decir, nombres de métodos y parámetros).

Cuando una interfaz tiene responsabilidades mixtas o agrega propiedades y métodos que no están relacionados con su propósito original, se está violando el ISP y se puede aumentar la complejidad y la dependencia de la interfaz.

Este principio se viola a menudo en las aplicaciones React, donde los componentes se ven obligados a depender de props que no necesitan solo porque se pasan desde un componente padre, esto puede llevar a problemas de mantenibilidad y claridad del código.

La manera correcta de implementar ISP en React es mediante el uso de HOCs (Higher Order Components).

Los HOCs son componentes que envuelven a otros componentes para proporcionarles funcionalidades adicionales, cuando se utilizan HOCs, se garantiza que cada componente solo tenga una responsabilidad y que las interfaces entre los componentes sigan siendo claras.

Cuando se crea un HOC, es tentador añadir lógica extra al componente que utiliza el HOC, sin embargo, esto viola el principio ISP y puede llevar a problemas en el futuro.

Es mejor mantener las responsabilidades de cada componente separadas y bien definidas.

\

Hay algunas formas diferentes de aplicar el principio ISP cuando se trabaja con componentes React:

\

1.

Crea métodos específicos de tus componentes para manejar eventos como envíos de formularios o clics de botones, y mantenlos en un componente HOC, de este modo, mantendrá la lógica y gestión de eventos separada del componente.

Al mantener la lógica de manejo de eventos separada del resto del código del componente, es más fácil mantener y reutilizar los componentes. Además, esta separación puede simplificar las pruebas de los componentes, ya que los manejadores de eventos pueden ser burlados o «stubbed» sin afectar al resto del código.

2.

Cuando compongas varios HOCs juntos, ponlos siempre en una función envolvente externa para que cada HOC sólo tenga acceso a sus dependencias directas..

Te muestro cómo usar múltiples HOCs juntos para crear un componente que siempre está envuelto en una función externa. Esto permitirá que cada HOC solo tenga acceso a sus dependencias directas.

function withFoo(Component) {
   return class extends React.Component {};
}
function withBar(Component) {
   return class extends React.Component {};
}
const MyEnhancedComponent = compose(withFoo, withBar)(MyBaseComponent);
Enter fullscreen mode Exit fullscreen mode

Puedes usar compose de Redux o recompose


Principio de Inversión de Dependencias (DIP)

Para mejorar la arquitectura del código y reducir el acoplamiento, este principio se basa en tres ideas clave:

Abstracción, inversión y dependencia.

La idea central del DIP es invertir las dependencias entre los módulos de una aplicación, lo que significa depender de abstracciones (interfaces) en lugar de depender directamente del funcionamiento interno de los módulos o de una clase.

Esto permite que los módulos individuales sean intercambiables sin necesidad de modificarlos o recompilarlos..

Las dependencias deben inyectarse mediante una interfaz y no directamente, en otras palabras, el principio DIP sugiere que los módulos de una aplicación deben estar altamente cohesionados pero bajamente acoplados.

Esto hace que el código sea más flexible y fácil de mantener.

Que es el alto acoplamiento y la Cohesión

  • Alto acoplamiento: El alto acoplamiento es una condición en la que dos o más componentes de software están fuertemente vinculados entre sí. Esto puede hacer que el software sea más difícil de mantener y probar.

  • Cohesión: La cohesión es una condición en la que los componentes de software están estrechamente relacionados entre sí y tienen un propósito claro. Esto puede hacer que el software sea más fácil de entender y mantener.

Al Reducir el acoplamiento y aumentar la cohesión, hacer que las clases sean independientes de las implementaciones específicas.

Esto hace que el código sea más flexible y fácil de mantener.

Por ejemplo, digamos que tienes una clase llamada ProductRepository que se utiliza para almacenar productos en una base de datos. La clase ProductRepository podría depender de una implementación específica de una base de datos, como MySQL o PostgreSQL. Esto haría que la clase ProductRepository estuviera estrechamente acoplada a la implementación específica de la base de datos.

Si quisieras cambiar la implementación de la base de datos a Oracle, tendrías que cambiar el código de la clase ProductRepository. Esto podría ser un proceso difícil y costoso.

En cambio, podrías usar el DIP para hacer que la clase ProductRepository dependa de una abstracción de una base de datos. Esto significaría que la clase ProductRepository sólo necesitaría saber cómo interactuar con una interfaz de base de datos, sin importar cómo se implemente esa interfaz.

La arquitectura hexagonal es un enfoque para la creación de software basado en el principio DIP, en lugar de tener módulos fuertemente acoplados, la arquitectura hexagonal permite que los módulos se comuniquen a través de interfaces abstractas, esto hace que sea mucho más fácil cambiar o reemplazar componentes sin impactar otros componentes del sistema.

Otra forma de aplicar el principio de inversión de dependencias es mediante la técnica de inyección de dependencias, que implica pasar objetos de una clase de bajo nivel a través del constructor o métodos de otra clase de alto nivel.

Por ejemplo, si tenemos una clase de alto nivel que necesita utilizar los servicios de una clase de bajo nivel, en lugar de crear una instancia de la clase de bajo nivel dentro de la clase de alto nivel, podemos pasar una instancia de la clase de bajo nivel a través del constructor o métodos de la clase de alto nivel.

De esta manera, la clase de alto nivel depende de una abstracción de la clase de bajo nivel, en lugar de depender directamente de la clase de bajo nivel en sí.

Hay muchas maneras de implementar DIP en una aplicación React, pero un enfoque común es utilizar el patrón de arquitectura hexagonal.

La arquitectura hexagonal también se conoce como arquitectura de puertos y adaptadores, y proporciona una forma limpia de separar una aplicación en componentes independientes que pueden comunicarse entre sí a través de interfaces bien definidas.

\

Algunos ejemplos de cómo la arquitectura DIP puede ser aplicada en React:

\

1.

Utilizar la inyección de dependencia, cuando se utiliza la inyección de dependencia, se pasan las dependencias a un componente desde fuera en lugar de codificarlas dentro del propio componente.

Esto hace que sea más fácil cambiar las dependencias más tarde si es necesario, y también hace que sea más fácil la pruebas unitarias o componentes mock ya que no tienen que preocuparse de burlarse de todas sus dependencias.

const MyComponent = ({ someDependency }) => { }; 
const someDependency = getSomeDependency(); 
<MyComponent someDependency={someDependency}
Enter fullscreen mode Exit fullscreen mode

2.

En React, una forma de invertir las dependencias es utilizar interfaces, las interfaces te permiten desacoplar tus componentes de implementaciones específicas de bibliotecas u otras dependencias, conexiones a base de datos, etc.

Si tienes un componente que necesita hacer una petición HTTP, puedes definir una interfaz para hacer peticiones HTTP y luego proporcionar una implementación concreta para cada entorno (desarrollo, producción).

3.

Digamos que quieres cambiar de usar una base de datos SQL a una base de datos NoSQL como MongoDB , con un enfoque tradicional por capas, esto requeriría cambios tanto en su capa de acceso a los datos (que interactúa con la base de datos) como en su capa de lógica de negocio (que utiliza los datos de la base de datos).

Sin embargo , si estas usando un enfoque DIP, puede simplemente cambiar el adaptador para su base de datos NoSQL y mantener toda su lógica de negocio intacta.

Esto hace que sea mucho más fácil y menos arriesgado para hacer cambios como este, ya que están aislados de la base del código fuente.

4.

Por supuesto, utilizar componentes de orden superior (HOC), mediante el uso de HOCs, podemos abstraer nuestras dependencias de nuestros componentes, haciéndolos más reutilizables y más fáciles de probar.

Por ejemplo, digamos que tenemos un componente que hace una llamada a la API para obtener datos:

const DataComponent = ({ url }) => {
   const [data, setData] = useState(null);
   useEffect(() => {
      fetch(url)
         .then((response) => response.json())
         .then((data) => setData(data));
   }, [url]);
   return data ? <div>{JSON.stringify(data)}</div> : null;
};
export default DataComponent;
Enter fullscreen mode Exit fullscreen mode

👆 Este componente obtiene datos de una API externa y los muestra en la pantalla, sin embargo, si queremos hacer prueba unitaria a este componente o reutilizarlo en otra parte de nuestra aplicación sin hacer una llamada real a la API (por ejemplo), no podríamos hacerlo debido a su dependencia del método fetch.

Podemos resolver este problema utilizando un HOC:

import React from 'react';
const withFetch = (WrappedComponent) => {
   class WithFetch extends React.Component {
      state = { data: null };
      async componentDidMount() {}
      render() {}
   }
   return WithFetch;
};
export default withFetch;
const DataComponent = WithFetch()(withProps({ url:'https://my-api/endpoint' })(DataCOmponent));
Enter fullscreen mode Exit fullscreen mode

👆 Ahora nuestro DataCOmponent sólo es responsable de mostrar la fecha recibida, y podemos probarlo fácilmente de forma aislada o reutilizarlo sin preocuparnos de sus dependencias.


El acrónimo STUPID, 6 Code Smell que debemos de evitar.

El código limpio es importante para cualquier proyecto de desarrollo de software, pero es especialmente importante cuando se trabaja con React.

La razón principal es que React se basa en gran medida en JavaScript, y el código limpio puede ayudar a asegurar que su código JavaScript es fácil de entender y mantener.

Los Code Smell de codificación son indicadores de un mal diseño o de problemas potenciales en el código, y suelen ser bastante fáciles de detectar una vez que se sabe qué buscar.

Hay algunas maneras diferentes de mantener tu código React limpio, pero una de las cosas más importantes a recordar es el acrónimo STUPID.

STUPID es un acrónimo de 6 Code Smell de código que deben evitarse al codificar en React:

S

Singleton: al singleton es un patrón de diseño de software que va en contra de (SRP), son malos porque pueden conducir a un acoplamiento estrecho y hacer que el código sea difícil de probar.

El patrón singleton restringe la instanciación de una clase a un solo objeto, esto es útil cuando sólo se necesita una instancia de una clase, como en el caso de una conexión de base de datos o un servicio de registro.

Sin embargo, el patrón singleton puede ser un antipatrón si se usa en exceso o de forma incorrecta.

Uno de los problemas de los singletons es que pueden conducir a un código difícil de probar y depurar, esto se debe a que todo el código que utiliza el singleton debe hacerlo a través del mismo método estático, lo que hace que sea difícil burlarse de las dependencias en las pruebas unitarias.

Además, los singletons pueden dificultar la comprensión de cómo interactúan los objetos entre sí en una aplicación, ya que todo debe pasar por la misma interfaz estática.

Otro problema con los singletons surge cuando se utilizan para la gestión del estado global.

Esto puede llevar a problemas como condiciones de carrera y problemas de seguridad de hilos.

Además, gestionar el estado global de esta manera hace más difícil razonar sobre el código y puede hacer que las aplicaciones sean más difíciles de refactorizar y escalar.

El acoplamiento estrecho se produce cuando dos piezas de código están estrechamente vinculadas entre sí, de manera que los cambios en una requieren cambios en la otra.

Esto puede hacer que el código sea difícil de mantener y depurar.

Recordemos el Principio de Responsabilidad Única: cada componente debe tener una única responsabilidad, y cada función debe tener un único propósito, los singletons claramente van en contra de esto.

Para manejar estados globales aconsejo usar a librerías como Redux y no usar un singleton, los singletons pueden ser difíciles de trabajar y a menudo conducen a un comportamiento inesperado.

T

Tight Coupling: alto acoplamiento, el alto acoplamiento entre los diferentes componentes de una aplicación React puede dificultar la reutilización o las pruebas de forma independiente .

Para reducir el acoplamiento , dividir los componentes grandes en otros más pequeños que son más fáciles de probar y reutilizar .

Además, utiliza props en lugar de estado siempre que sea posible para que los cambios en un componente no afecten a otros innecesariamente.

U

Untestability: código no probable (unit test), una de las mayores ventajas de React es su testabilidad pero si tu código no está escrito correctamente puede ser muy difícil de probar..

Asegúrate de que tu código sea modular para poder aislar las diferentes partes para su testeo.

El código que no es probado por unit test es a menudo referido como “no probable”.

Esto significa que si algo va mal, es difícil decir dónde se originó el problema, como resultado, la depuración y corrección de errores puede llevar mucho tiempo.

Recomiendo siempre escribir pruebas unitarias para sus componentes React ( utilizando bibliotecas como Jest ) antes de desplegarlos en la producción .

P

Premature optimization: optimizaciones prematuras, es común que un desarrollador nuevo en React (o cualquier marco de trabajo frontal) pasen demasiado tiempo optimizando su código antes de que sea realmente necesario «Optimizar» el código, generalmente esto significa hacer concesiones por lo general sacrificar la legibilidad o la flexibilidad a cambio de ganancias de rendimiento.

Pero la optimización prematura casi nunca es rentable porque la mayoría de las aplicaciones no se optimizan innecesariamente hasta que llegan a millones de usuarios.

Así que, a no ser que estés construyendo el próximo Facebook, resiste la tentación de modificar cualquier cosa en busca de ganancias marginales de rendimiento 🤜🤛🤓

I

Indescriptive Naming: nombres poco descriptivos, la elección de buenos nombres para las variables, las funciones y los archivos es uno de los aspectos más importantes a la hora de escribir un código legible.

Desgraciadamente, muchos desarrolladores eligen nombres demasiado genéricos (por ejemplo, «data») o demasiado específicos (por ejemplo, «userDetailsForPage17»).

Los buenos nombres deben ser lo suficientemente descriptivos para que cualquiera que lea el código pueda entender lo que ocurre sin tener que consultar documentación adicional.

La nomenclatura es uno de los aspectos más importantes del desarrollo de software porque puede tener un gran impacto en la legibilidad y la capacidad de mantenimiento del código.

Los buenos nombres hacen que el código sea más fácil de entender y de trabajar con él; también lo hacen más resistente a los cambios. Por otro lado, los malos nombres pueden hacer que el código sea confuso y difícil de trabajar, lo que conduce a más errores y a un aumento de los costes de mantenimiento en el futuro.

¿Cómo evitar caer en esta trampa? Cuando elijas los nombres de tus variables, constantes, funciones, etc., ten en cuenta estos consejos:

  • Asegúrate de que tus nombres son lo suficientemente descriptivos como para que alguien que lea tu código sea capaz de entender lo que representan sin tener que buscar información adicional en otra parte (por ejemplo, comentarios o documentación).

  • Evita los nombres de variables de una sola letra a menos que se utilicen como parte de una convención establecida (por ejemplo, i para los contadores de los bucles).

  • Utiliza convenciones de nomenclatura consistentes en todo el proyecto para que construcciones similares tengan nombres similares (por ejemplo, si utilizas camel case para los nombres de las variables, quédate con ello en lugar de mezclar las cosas con snake case o Pascal case)

Algunos ejemplos:

  1. “Foo” y “bar” son nombres comunes utilizados en programación.

No son descriptivos de lo que la función o variable está haciendo realmente.

En React, esto sería un ejemplo de un componente mal nombrado:

const Foo = () => <div> foo </div>;
Enter fullscreen mode Exit fullscreen mode

👆 ¿Qué significa “foo”? ¿Es un verbo o un sustantivo? No tenemos ni idea.

  1. Otro ejemplo de nombre no descriptivo sería utilizar letras simples como nombres de funciones o variables.

Esto se ve a menudo en las ecuaciones matemáticas en las que x representa algún valor desconocido:

const averageScore = (x, y) => (x + y) / 2;
Enter fullscreen mode Exit fullscreen mode

👆 ¿Qué representan aquí x e y? No podemos saberlo por el nombre.

^ — -

Esto también ayudará a mejorar la comprensión y a reducir la confusión cuando se lea o trabaje con el código de otra persona.

Si tiene dificultades para encontrar un buen nombre, dé un paso atrás e intente describir lo que representa exactamente esta construcción en inglés — esto le dará algunas pistas sobre posibles candidatos.

D

Duplication: duplicidad de código, no aplicar el principio DRY, la duplicación de código es uno de los problemas más comunes en las aplicaciones React.

Es importante recordar el principio DRY cuando se codifica en React: No te repitas.

Esto significa que debes evitar duplicar código siempre que sea posible, esto no solo hace que tu código sea más difícil de mantener, sino que también puede conducir a errores y problemas de rendimiento.

Si te encuentras creando múltiples componentes que son muy similares, podría ser el momento de refactorizar tu código y extraer alguna funcionalidad común en un componente compartido.

O bien, si te encuentras duplicando props o estados a través de múltiples componentes, podría ser el momento de mover esos datos a un componente padre para que puedan ser compartidos a través de los componentes hijos.

Tómate siempre un momento para parar y pensar si hay una forma mejor de estructurar tu código React antes de seguir añadiendo más funciones.

Siguiendo el principio DRY, acabarás teniendo aplicaciones React más limpias y fáciles de mantener a largo plazo.

— -*

Evitando estos Code Smell de codificación en tus propios proyectos (o corrigiéndolos si ya se han colado), puedes ayudar a asegurar que tus aplicaciones React están construidas sobre una base sólida.

Con el tiempo les iré agregando más información a la guía, espero que la disfruten y pongan en práctica toda esta información en sus desarrollos.
🤜🤛🤓🚀🚀🚀

— FIN —

Top comments (0)