<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Josué Oroya</title>
    <description>The latest articles on DEV Community by Josué Oroya (@joshuacba08).</description>
    <link>https://dev.to/joshuacba08</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F505379%2Fbea3914f-3306-448a-b51e-fbf28f7c66d7.jpeg</url>
      <title>DEV Community: Josué Oroya</title>
      <link>https://dev.to/joshuacba08</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/joshuacba08"/>
    <language>en</language>
    <item>
      <title>¿Estás aplicando un anti-patrón de arquitectura en el Frontend?</title>
      <dc:creator>Josué Oroya</dc:creator>
      <pubDate>Wed, 07 Jan 2026 18:54:16 +0000</pubDate>
      <link>https://dev.to/joshuacba08/estas-aplicando-un-anti-patron-de-arquitectura-en-el-frontend-2p8m</link>
      <guid>https://dev.to/joshuacba08/estas-aplicando-un-anti-patron-de-arquitectura-en-el-frontend-2p8m</guid>
      <description>&lt;p&gt;Al iniciar un proyecto tanto en el Frontend como en el Backend, generalmente definimos muchos aspectos de nuestro software de acuerdo a los requerimientos que se nos piden. Sin embargo, con el tiempo el proyecto crece y se vuelve más complejo, y es aquí donde pueden aparecer los &lt;strong&gt;anti-patrones de arquitectura&lt;/strong&gt;. En este artículo veremos algunos puntos que pueden diagnosticar que estamos aplicando un anti-patrón de arquitectura en el Frontend sin saberlo, y lo más importante: &lt;strong&gt;cómo solucionarlos&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F95g18ynjrybzogzi4st3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F95g18ynjrybzogzi4st3.png" alt="Portada" width="800" height="619"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es y por qué es importante la arquitectura en el Frontend?
&lt;/h2&gt;

&lt;p&gt;Antes que nada, me gustaría definir un poco acerca de lo que significa &lt;code&gt;arquitectura&lt;/code&gt; en el desarrollo de software. Si eres nuevo en el mundo de la programación, es posible que hayas escuchado este término pero no sepas exactamente a qué se refiere.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Arquitectura de software&lt;/strong&gt; es la estructura de alto nivel de un sistema de software, la disciplina de crear tales estructuras, y la documentación de estas estructuras. — &lt;em&gt;Software Architecture in Practice, Bass et al.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;En palabras simples, una arquitectura en el desarrollo de software es la estructura que define cómo se organizarán los diferentes componentes de un sistema y cómo interactuarán entre sí. Además, la arquitectura define las reglas y los principios que guiarán el desarrollo del software.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9droypxui0f9hnc9glz9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9droypxui0f9hnc9glz9.png" alt="pilares" width="800" height="589"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Una &lt;strong&gt;buena arquitectura es fundamental para aplicar y mantener un buen flujo de trabajo para todos los desarrolladores implicados en el proyecto&lt;/strong&gt;, así como también facilita que nuevos equipos o miembros se sumen al proyecto sin mayores problemas. Además, una correcta arquitectura hace que la base de código sea más mantenible, escalable y testeable. En pocas palabras, &lt;strong&gt;incrementa la calidad del software y la productividad de los equipos de desarrollo&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Los pilares de una buena arquitectura Frontend
&lt;/h3&gt;

&lt;p&gt;Para entender mejor qué hace que una arquitectura sea "buena", veamos sus pilares fundamentales:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pilar&lt;/th&gt;
&lt;th&gt;Descripción&lt;/th&gt;
&lt;th&gt;Ejemplo práctico&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Separación de responsabilidades&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cada módulo tiene una única responsabilidad&lt;/td&gt;
&lt;td&gt;Componentes UI separados de la lógica de negocio&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bajo acoplamiento&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Los módulos dependen lo menos posible entre sí&lt;/td&gt;
&lt;td&gt;Usar interfaces y abstracciones&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Alta cohesión&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Elementos relacionados están agrupados&lt;/td&gt;
&lt;td&gt;Features o dominios bien definidos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Escalabilidad&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;El sistema puede crecer sin reestructuración mayor&lt;/td&gt;
&lt;td&gt;Arquitectura modular&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Testeabilidad&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Facilidad para escribir y ejecutar tests&lt;/td&gt;
&lt;td&gt;Dependencias inyectables&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foblk5bt9374ug39jf34n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foblk5bt9374ug39jf34n.png" alt="pilares_arquitectura" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Del otro lado del río: los anti-patrones de arquitectura
&lt;/h2&gt;

&lt;p&gt;Luego de la breve explicación acerca de aplicar una buena arquitectura en el Frontend, es importante hacer una contraposición con los anti-patrones de arquitectura.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Un &lt;strong&gt;anti-patrón&lt;/strong&gt; es una respuesta común a un problema recurrente que es usualmente inefectiva y tiene el riesgo de ser altamente contraproducente. — &lt;em&gt;AntiPatterns: Refactoring Software, Architectures, and Projects in Crisis&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para entender mejor el concepto, aplicaremos una hipótesis con su respectiva contra-hipótesis:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fscyo6hwyo7pwyhpllueb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fscyo6hwyo7pwyhpllueb.png" alt="cotra hipotesis" width="800" height="541"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hipótesis&lt;/strong&gt;: "Una buena arquitectura mantiene un buen flujo de trabajo para todo el equipo de desarrollo".&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Contra-hipótesis&lt;/strong&gt;: "Un anti-patrón de arquitectura puede generar un mal flujo de trabajo para todo el equipo de desarrollo".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hipótesis&lt;/strong&gt;: "Una buena arquitectura facilita la incorporación de nuevos miembros al equipo de desarrollo".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Contra-hipótesis&lt;/strong&gt;: "Un anti-patrón de arquitectura puede dificultar la incorporación de nuevos miembros al equipo de desarrollo".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hipótesis&lt;/strong&gt;: "Una buena arquitectura hace que la base de código sea más mantenible, escalable y testeable".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Contra-hipótesis&lt;/strong&gt;: "Un anti-patrón de arquitectura puede hacer que la base de código sea menos mantenible, escalable y testeable".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hipótesis&lt;/strong&gt;: "Una buena arquitectura incrementa la calidad del software y la productividad de los equipos de desarrollo".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Contra-hipótesis&lt;/strong&gt;: "Un anti-patrón de arquitectura puede disminuir la calidad del software y la productividad de los equipos de desarrollo".&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sinceramente, la primera vez que me planteé estos puntos, quedé sorprendido por lo mal que se oyen las contra-hipótesis. Sin embargo, es importante tener en cuenta que &lt;strong&gt;los anti-patrones de arquitectura pueden aparecer en cualquier proyecto sin que nos demos cuenta&lt;/strong&gt;. Por eso, es importante estar atentos a ciertos puntos que pueden diagnosticar que estamos aplicando un anti-patrón de arquitectura en el Frontend.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Estás aplicando un anti-patrón de arquitectura en el Frontend?
&lt;/h2&gt;

&lt;p&gt;Los anti-patrones de arquitectura no son algo que se aplique de manera intencional, sin embargo, ningún proyecto está exento de ellos. A continuación, veremos los anti-patrones más comunes en el desarrollo Frontend y cómo identificarlos:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. El "Spaghetti Code" o la Gran Bola de Lodo (Big Ball of Mud)
&lt;/h3&gt;

&lt;p&gt;Este es probablemente el anti-patrón más común y peligroso. Se caracteriza por una falta total de estructura visible, donde el código crece de manera orgánica y desordenada.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmokbnw3pxtb5nnxvrozf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmokbnw3pxtb5nnxvrozf.png" alt="Antipatron" width="800" height="665"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Síntomas:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No existe una separación clara de capas&lt;/li&gt;
&lt;li&gt;Componentes con múltiples responsabilidades (más de 500 líneas)&lt;/li&gt;
&lt;li&gt;Dependencias circulares entre módulos&lt;/li&gt;
&lt;li&gt;Dificultad para encontrar dónde está la lógica de una funcionalidad&lt;/li&gt;
&lt;li&gt;Los cambios en un lugar rompen funcionalidades en otros lugares&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solución:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgoly25edqox21a8eb8et.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgoly25edqox21a8eb8et.png" alt="arquitectura" width="800" height="1065"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. El Componente Dios (God Component)
&lt;/h3&gt;

&lt;p&gt;Un componente que hace demasiadas cosas: maneja estado, hace llamadas a APIs, contiene lógica de negocio, y renderiza UI compleja.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxpvpoeq8z3s3lkyu0jti.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxpvpoeq8z3s3lkyu0jti.png" alt="god_component" width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo de un God Component (Mal):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// UserDashboard.jsx - 800+ líneas&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;UserDashboard&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setOrders&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;notifications&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setNotifications&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setSettings&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;({});&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsLoading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// ... 50 más estados&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Fetch user, orders, notifications, settings...&lt;/span&gt;
    &lt;span class="c1"&gt;// Lógica de transformación de datos&lt;/span&gt;
    &lt;span class="c1"&gt;// Manejo de errores&lt;/span&gt;
    &lt;span class="c1"&gt;// WebSocket connections&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="cm"&gt;/* muchas dependencias */&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleUpdateProfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleDeleteOrder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleMarkNotificationRead&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="c1"&gt;// ... 30 más handlers&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="c1"&gt;// 500+ líneas de JSX&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solución - Composición y separación:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftgnxqb865di92rw7bmvx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftgnxqb865di92rw7bmvx.png" alt="composición y separación" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Acoplamiento Excesivo (Tight Coupling)
&lt;/h3&gt;

&lt;p&gt;Cuando los componentes o módulos dependen demasiado de la implementación interna de otros, cualquier cambio se convierte en una pesadilla.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fifcnp2lbe02poj3xa1y3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fifcnp2lbe02poj3xa1y3.png" alt="acoplamiento" width="800" height="831"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Síntomas:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cambiar un componente requiere modificar muchos otros&lt;/li&gt;
&lt;li&gt;Los tests requieren mockear muchas dependencias&lt;/li&gt;
&lt;li&gt;Componentes importan directamente de rutas profundas de otros módulos&lt;/li&gt;
&lt;li&gt;Props drilling excesivo (pasar props a través de 5+ niveles)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solución - Inversión de dependencias:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flisb583dgdup8omi3eb4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flisb583dgdup8omi3eb4.png" alt="Solution" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. La Carpeta "Utils" o "Helpers" Infinita
&lt;/h3&gt;

&lt;p&gt;Una carpeta que se convierte en el cajón de sastre donde va todo lo que "no sabemos dónde poner".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fumzc6ytafhxy0xj7jaoe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fumzc6ytafhxy0xj7jaoe.png" alt="utils_folder" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Estructura problemática (Mal):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├── utils/
│   ├── helpers.js          # 2000 líneas
│   ├── functions.js        # 1500 líneas
│   ├── misc.js             # ???
│   ├── common.js           # Más de lo mismo
│   └── index.js            # Re-exporta todo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solución - Organización por dominio:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flp5rjyzt1mnlu950q0h6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flp5rjyzt1mnlu950q0h6.png" alt="org domain" width="800" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. El Estado Global Descontrolado (Global State Soup)
&lt;/h3&gt;

&lt;p&gt;Usar estado global para todo, incluso para estado que debería ser local.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F66o3umvd3uqxxi0st8yo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F66o3umvd3uqxxi0st8yo.png" alt="Global state" width="800" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Síntomas:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El store global tiene cientos de propiedades&lt;/li&gt;
&lt;li&gt;Estado de formularios en Redux/Zustand&lt;/li&gt;
&lt;li&gt;Valores temporales o de UI en estado global&lt;/li&gt;
&lt;li&gt;Dificultad para rastrear qué modifica qué&lt;/li&gt;
&lt;li&gt;Re-renders innecesarios en toda la aplicación&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solución - Separación de responsabilidades de estado:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4mkoba3j4a3jcfbct7w0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4mkoba3j4a3jcfbct7w0.png" alt="separacion de responsabilidades" width="800" height="713"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  6. La Abstracción Prematura (Premature Abstraction)
&lt;/h3&gt;

&lt;p&gt;Crear abstracciones complejas antes de que sean necesarias, "por si acaso". Este es un error común cuando se intenta aplicar patrones de diseño sin una necesidad real, muchas veces motivado por:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Haber leído recientemente sobre un patrón de diseño y querer aplicarlo&lt;/li&gt;
&lt;li&gt;Miedo a tener que refactorizar en el futuro&lt;/li&gt;
&lt;li&gt;Presión por escribir código "profesional" o "escalable"&lt;/li&gt;
&lt;li&gt;No distinguir entre complejidad esencial y complejidad accidental&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Debo reconocer que he caído en este anti-patrón en varias ocasiones cuando aún tenía poca experiencia en desarrollo de software. En algún momento de mi carrera, me di cuenta que con algunas preguntas simples podía evitar caer en este anti-patrón:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pregunta&lt;/th&gt;
&lt;th&gt;Si la respuesta es NO...&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;¿Realmente necesito esta abstracción ahora?&lt;/td&gt;
&lt;td&gt;Espera a tener el caso de uso real&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¿Estoy resolviendo un problema real o uno hipotético?&lt;/td&gt;
&lt;td&gt;No resuelvas problemas que no existen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¿Esta abstracción añade valor o solo complejidad?&lt;/td&gt;
&lt;td&gt;Mantén la solución simple&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¿Puedo implementar esto de manera más simple primero?&lt;/td&gt;
&lt;td&gt;Hazlo simple y refactoriza después&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  La Regla del Tres
&lt;/h4&gt;

&lt;p&gt;Un principio útil para decidir cuándo abstraer es la &lt;strong&gt;Regla del Tres&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnfr60v0n6l2aua4rw457.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnfr60v0n6l2aua4rw457.png" alt="Regla de 3" width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Ejemplo: Sobre-ingeniería vs. Solución pragmática
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Mal - Sobre-ingeniería para un simple botón:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 8 archivos, 200+ líneas para... un botón&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IButtonStrategy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IButtonProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IButtonStrategy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IButtonBuilder&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SubmitButtonStrategy&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IButtonStrategy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IFormValidator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CancelButtonStrategy&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IButtonStrategy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ButtonStrategyFactory&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ButtonBuilder&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IButtonBuilder&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AbstractButton&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;BaseComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Para al final renderizar:&lt;/span&gt;
&lt;span class="c1"&gt;// &amp;lt;button onClick={strategy.execute}&amp;gt;Submit&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Bien - Solución simple que resuelve el problema real:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Un componente, ~30 líneas&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cancel&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;disabled&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bg-blue-500 text-white&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bg-gray-200 text-gray-700&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bg-white border border-gray-300&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; 
      &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt; 
      &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Principios a seguir
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;"Make it work, make it right, make it fast" — Kent Beck&lt;/p&gt;

&lt;p&gt;"Duplication is far cheaper than the wrong abstraction" — Sandi Metz&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsn3i4jlavxtoab4aj1jj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsn3i4jlavxtoab4aj1jj.png" alt="solution 2" width="800" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La clave está en encontrar el equilibrio: &lt;strong&gt;ni sobre-ingeniería ni código duplicado sin sentido&lt;/strong&gt;. La abstracción correcta emerge cuando tienes suficiente contexto sobre el problema real.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. El Copy-Paste Driven Development
&lt;/h3&gt;

&lt;p&gt;Copiar y pegar código en lugar de crear abstracciones reutilizables cuando SÍ son necesarias. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Síntomas:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Múltiples componentes con código casi idéntico&lt;/li&gt;
&lt;li&gt;Cambios que requieren modificar muchos archivos&lt;/li&gt;
&lt;li&gt;Bugs que se arreglan en un lugar pero persisten en otros&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa3whnj9q09op0ygnilq5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa3whnj9q09op0ygnilq5.png" alt="explain" width="800" height="207"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Checklist de diagnóstico
&lt;/h2&gt;

&lt;p&gt;Utiliza esta checklist para evaluar tu proyecto:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pregunta&lt;/th&gt;
&lt;th&gt;Bien&lt;/th&gt;
&lt;th&gt;Problema&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;¿Un nuevo desarrollador puede entender la estructura en &amp;lt; 1 hora?&lt;/td&gt;
&lt;td&gt;Sí&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¿Puedes añadir una feature sin modificar código existente?&lt;/td&gt;
&lt;td&gt;Sí&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¿Los componentes tienen &amp;lt; 200 líneas de código?&lt;/td&gt;
&lt;td&gt;Mayoría&lt;/td&gt;
&lt;td&gt;Pocos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¿Existe documentación de la arquitectura?&lt;/td&gt;
&lt;td&gt;Sí&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¿Los tests son fáciles de escribir?&lt;/td&gt;
&lt;td&gt;Sí&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¿El estado global tiene &amp;lt; 20 propiedades?&lt;/td&gt;
&lt;td&gt;Sí&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¿Las carpetas utils tienen &amp;lt; 10 archivos?&lt;/td&gt;
&lt;td&gt;Sí&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  El camino hacia una mejor arquitectura
&lt;/h2&gt;

&lt;p&gt;Si identificaste varios de estos anti-patrones en tu proyecto, no te preocupes. La refactorización es un proceso gradual.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0n4s3ilccfa0r2sx5k8f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0n4s3ilccfa0r2sx5k8f.png" alt="solution 2" width="800" height="1396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Recomendaciones finales
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Documenta tu arquitectura&lt;/strong&gt;: Usa ADRs (Architecture Decision Records) para registrar el "por qué" de las decisiones.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Establece convenciones&lt;/strong&gt;: Define una estructura de carpetas clara y consistente.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Revisa el código en equipo&lt;/strong&gt;: Los code reviews ayudan a detectar anti-patrones temprano.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mide y monitorea&lt;/strong&gt;: Usa herramientas como SonarQube, ESLint con reglas de complejidad, y métricas de cobertura.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Aprende de otros&lt;/strong&gt;: Estudia arquitecturas probadas como Feature-Sliced Design, Atomic Design, o Clean Architecture adaptada a Frontend.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;Los anti-patrones de arquitectura son como la deuda técnica silenciosa: no los notamos hasta que el proyecto se vuelve difícil de mantener. La clave está en:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Detectar temprano&lt;/strong&gt;: Revisa regularmente la salud de tu código&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aprender continuamente&lt;/strong&gt;: Estudia patrones de arquitectura&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comunicar con el equipo&lt;/strong&gt;: Las decisiones de arquitectura son decisiones de equipo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Balancear&lt;/strong&gt;: Ni sobre-ingeniería ni código espagueti&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;¿Has identificado alguno de estos anti-patrones en tus proyectos? ¡Comparte tu experiencia en los comentarios!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Referencias:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Clean Architecture&lt;/em&gt; - Robert C. Martin&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Patterns of Enterprise Application Architecture&lt;/em&gt; - Martin Fowler&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;AntiPatterns: Refactoring Software, Architectures, and Projects in Crisis&lt;/em&gt; - Brown et al.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;¿Te gustó este artículo? Sígueme para más contenido sobre arquitectura Frontend y buenas prácticas de desarrollo.&lt;/em&gt; &lt;/p&gt;

</description>
      <category>architecture</category>
      <category>frontend</category>
      <category>antipattern</category>
      <category>programming</category>
    </item>
    <item>
      <title>El propósito del Testing</title>
      <dc:creator>Josué Oroya</dc:creator>
      <pubDate>Thu, 06 Nov 2025 12:14:33 +0000</pubDate>
      <link>https://dev.to/joshuacba08/el-proposito-del-testing-5571</link>
      <guid>https://dev.to/joshuacba08/el-proposito-del-testing-5571</guid>
      <description>&lt;p&gt;En ingeniería de software, &lt;strong&gt;todo programa funciona… hasta que deja de hacerlo&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Y cuando lo hace, rara vez avisa.&lt;/p&gt;

&lt;p&gt;El testing no existe para demostrar que algo “anda bien”, sino para &lt;strong&gt;entender bajo qué condiciones deja de hacerlo&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Es una práctica que revela lo que el entusiasmo del desarrollo suele ocultar: las grietas invisibles en nuestras suposiciones.&lt;/p&gt;




&lt;h2&gt;
  
  
  El costo real de los errores en producción
&lt;/h2&gt;

&lt;p&gt;Corregir un bug nunca cuesta lo mismo. Según el &lt;strong&gt;NIST (National Institute of Standards and Technology)&lt;/strong&gt;, el precio de un error se multiplica a medida que avanza el ciclo de desarrollo:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Etapa&lt;/th&gt;
&lt;th&gt;Costo relativo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Diseño&lt;/td&gt;
&lt;td&gt;1x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Codificación&lt;/td&gt;
&lt;td&gt;5x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Testing&lt;/td&gt;
&lt;td&gt;10x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Producción&lt;/td&gt;
&lt;td&gt;30x a 100x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Esto no es teoría: es matemática empresarial.&lt;br&gt;&lt;br&gt;
En 2020, el &lt;strong&gt;Consortium for IT Software Quality (CISQ)&lt;/strong&gt; estimó que el costo de software defectuoso para la economía estadounidense fue de &lt;strong&gt;$2.08 trillones&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
No es que “los bugs cuesten caro”, es que &lt;strong&gt;las decisiones sin testing salen carísimas&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Errores que resultaron muy costosos
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Knight Capital Group (2012)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Un despliegue incompleto activó código obsoleto y generó pérdidas de &lt;strong&gt;$440 millones en 45 minutos&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Una empresa entera colapsó por un flag mal configurado.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ariane 5 (1996)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Un overflow al convertir un número de 64 bits a 16 provocó la explosión de un cohete valuado en &lt;strong&gt;$370 millones&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
El código “reutilizado” de Ariane 4 jamás fue testeado bajo las nuevas condiciones.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Therac-25 (1985–1987)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Una máquina de radioterapia administró dosis letales debido a errores de concurrencia.&lt;br&gt;&lt;br&gt;
Seis personas murieron. No por hardware, sino por software no validado.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Toyota (2010)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Un fallo de software en el sistema de aceleración llevó al retiro de &lt;strong&gt;9 millones de vehículos&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Investigaciones posteriores revelaron race conditions y fallos en la gestión de memoria.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  El verdadero enemigo: lo que no se ve
&lt;/h2&gt;

&lt;p&gt;En mi experiencia trabajando con equipos distribuidos y productos en producción, aprendí que los peores errores no son los que hacen explotar todo de inmediato.&lt;br&gt;&lt;br&gt;
Son los que &lt;strong&gt;parecen inofensivos&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
los que corrompen datos lentamente, los que rompen un flujo solo en ciertas condiciones, los que hacen que algo “a veces no funcione”.&lt;/p&gt;

&lt;p&gt;Esos son los que degradan la experiencia del usuario y erosionan la confianza en el producto.&lt;br&gt;&lt;br&gt;
Y cuando la confianza se pierde, ni mil tests la recuperan.&lt;/p&gt;

&lt;p&gt;Por eso, el testing no es solo un mecanismo técnico:&lt;br&gt;&lt;br&gt;
es la forma en que &lt;strong&gt;hacemos visibles las fallas invisibles&lt;/strong&gt; antes de que lo hagan nuestros usuarios.&lt;/p&gt;




&lt;h2&gt;
  
  
  El propósito fundamental: gestionar el riesgo
&lt;/h2&gt;

&lt;p&gt;Cada prueba, cada mock, cada test end-to-end tiene un mismo fin: &lt;strong&gt;reducir el riesgo&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
No testeamos por costumbre ni por obligación, sino porque el software &lt;strong&gt;vive en entornos impredecibles&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Los usuarios siempre encuentran combinaciones que nadie anticipó.
&lt;/li&gt;
&lt;li&gt;Las redes fallan justo en el peor momento.
&lt;/li&gt;
&lt;li&gt;Los servicios externos cambian sin avisar.
&lt;/li&gt;
&lt;li&gt;Los requisitos evolucionan mientras el sprint aún está en curso.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Testing no es buscar errores: es &lt;strong&gt;mapear la incertidumbre&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Es una forma de humildad profesional —reconocer que el código no es infalible y que las buenas intenciones no previenen bugs.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwdweikone0nz50mmr19a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwdweikone0nz50mmr19a.png" alt="Modelo de flujo" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing en el mundo web (mi mundo): la frontera entre frontend y backend
&lt;/h2&gt;

&lt;p&gt;En el desarrollo web moderno, la línea entre frontend y backend se ha vuelto delgada.&lt;br&gt;&lt;br&gt;
Un error en el backend puede romper una vista entera, y una validación omitida en el frontend puede inyectar datos inválidos en la base.  &lt;/p&gt;

&lt;p&gt;Un &lt;strong&gt;frontend developer&lt;/strong&gt; prueba la experiencia: flujos, formularios, accesibilidad, estados límite.&lt;br&gt;&lt;br&gt;
Un &lt;strong&gt;backend developer&lt;/strong&gt; prueba la integridad: transacciones, respuestas, consistencia de datos y resiliencia ante errores externos.&lt;/p&gt;

&lt;p&gt;Ambos están del mismo lado: el de quienes &lt;strong&gt;quieren dormir tranquilos después del deploy un viernes por la tarde (Por favor, no despliegues un día así)&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Una cultura, no una fase
&lt;/h2&gt;

&lt;p&gt;Testing no debería ser un paso al final del sprint, sino una &lt;strong&gt;forma de pensar&lt;/strong&gt; durante todo el desarrollo.&lt;br&gt;&lt;br&gt;
Diseñar código testeable es diseñar código &lt;strong&gt;legible, mantenible y confiable&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Automatizar tests no es burocracia: es &lt;strong&gt;seguridad futura&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Adoptar una cultura de testing no solo mejora la calidad técnica, sino también la &lt;strong&gt;comunicación entre equipos&lt;/strong&gt;, la &lt;strong&gt;velocidad de entrega&lt;/strong&gt; y, sobre todo, la &lt;strong&gt;confianza en el proceso&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Sinceramente, reconozco buenos equipos y buenos líderes cuando al mencionar estimar tests, le dan la prioridad que debe tener.&lt;/p&gt;




&lt;h2&gt;
  
  
  Epílogo: el tester invisible
&lt;/h2&gt;

&lt;p&gt;El testing no es el 10 de las entregas. No brilla en las demos ni figura en las métricas.&lt;br&gt;&lt;br&gt;
Pero es la base silenciosa sobre la que se sostiene todo lo demás. &lt;br&gt;
Creo que todos hemos trabajado en proyectos que en algún momento se vuelven tan grandes que cualquier mínimo cambio rompe la aplicación, pero coincidentemente, los equipos que aplican un proceso serio de testing pocas veces tienen estos problemas.&lt;/p&gt;

&lt;p&gt;Cada vez que un usuario confía, que una API responde bien, que un sistema escala sin romperse,&lt;br&gt;&lt;br&gt;
hay una línea de test que lo permitió.  &lt;/p&gt;

</description>
      <category>testing</category>
      <category>testdev</category>
      <category>javascript</category>
      <category>unittest</category>
    </item>
    <item>
      <title>La AI es perezosa y eso no está mal</title>
      <dc:creator>Josué Oroya</dc:creator>
      <pubDate>Mon, 09 Jun 2025 20:10:00 +0000</pubDate>
      <link>https://dev.to/joshuacba08/la-ai-es-perezosa-y-eso-no-esta-mal-3319</link>
      <guid>https://dev.to/joshuacba08/la-ai-es-perezosa-y-eso-no-esta-mal-3319</guid>
      <description>&lt;p&gt;Hace tiempo que venimos integrando herramientas de inteligencia artificial en nuestro flujo de trabajo diario. Desde ChatGPT hasta modelos más especializados, la AI ha demostrado ser una aliada poderosa para mejorar nuestra productividad y eficiencia. Sin embargo, hay un aspecto que rara vez se menciona: &lt;strong&gt;la AI es perezosa por naturaleza&lt;/strong&gt;. Y eso, lejos de ser un defecto, puede ser una virtud.&lt;/p&gt;




&lt;h2&gt;
  
  
  Un caso real: cuando la pereza se hizo evidente
&lt;/h2&gt;

&lt;p&gt;En uno de mis proyectos de desarrollo, decidí automatizar la creación de archivos &lt;code&gt;.json&lt;/code&gt; de gran volumen, que normalmente se llenaban a mano. La idea era simple: pedirle a ChatGPT (versión 4o) que generara un archivo con una estructura específica y, a partir de ahí, completar los datos necesarios.&lt;/p&gt;

&lt;p&gt;Todo iba bien, hasta que noté que la AI no podía generar el archivo completo de una sola vez. En cambio, me entregaba fragmentos que yo debía ensamblar. Por suerte, conocía bien el proyecto y el lenguaje, así que completar el rompecabezas no fue un problema.&lt;/p&gt;

&lt;p&gt;Días después, el modelo de datos cambió. Eso implicó actualizar decenas de archivos &lt;code&gt;.interface.ts&lt;/code&gt; y &lt;code&gt;.json&lt;/code&gt;. Como eran tareas de alta carga y baja complejidad, decidí delegarlas en un &lt;strong&gt;Agente AI&lt;/strong&gt; con prompts bien definidos. Pero, al revisar los resultados, noté algo inquietante: se habían eliminado funciones importantes de mi store con Zustand, funciones que no debían tocarse.&lt;/p&gt;

&lt;p&gt;Y ahí entendí el patrón: la AI había tomado atajos. No por maldad, sino porque su diseño la empuja a ser eficiente a cualquier costo. Incluso si eso significa borrar lo que cree innecesario.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reflexión: ¿defecto o característica?
&lt;/h2&gt;

&lt;p&gt;Lo admito, me enojé. Había confiado en la AI para encargarse de tareas tediosas, y terminé corrigiendo errores evitables. Pero, al analizarlo en frío, me di cuenta de algo importante: &lt;strong&gt;la pereza de la AI no es un bug. Es una feature&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  La pereza como virtud
&lt;/h2&gt;

&lt;p&gt;La AI está diseñada para optimizar. No busca hacer las cosas bien, sino hacerlas lo suficientemente bien con el menor esfuerzo posible. En vez de recorrer un camino largo y detallado, elige atajos.&lt;/p&gt;

&lt;p&gt;Y, si lo pensás, no está tan lejos del mindset de los programadores: evitar el trabajo innecesario, automatizar lo repetitivo, y buscar soluciones simples a problemas complejos. &lt;strong&gt;La AI, en esencia, es un programador perezoso con esteroides.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ¿Qué significa “pereza” en términos técnicos?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6dfy53ptbtp344vi4ga5.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6dfy53ptbtp344vi4ga5.webp" alt="Lazy Evaluation" width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Muchos modelos de AI (y frameworks de programación) aplican un principio conocido como &lt;em&gt;evaluación perezosa&lt;/em&gt; (&lt;em&gt;lazy evaluation&lt;/em&gt;). En pocas palabras, &lt;strong&gt;no se hace nada hasta que realmente se necesita&lt;/strong&gt;. Esto ahorra recursos y tiempo, pero también puede hacer que algunas cosas se pasen por alto si no se supervisa bien.&lt;/p&gt;




&lt;h2&gt;
  
  
  La importancia de la supervisión humana
&lt;/h2&gt;

&lt;p&gt;La AI es útil, pero no infalible. Su tendencia a cortar camino puede llevar a errores sutiles pero importantes. Por eso, &lt;strong&gt;la supervisión humana no es opcional&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;En mi caso, revisar cuidadosamente el código generado me permitió detectar y corregir omisiones antes de que se transformaran en bugs difíciles de rastrear.&lt;/p&gt;

&lt;p&gt;La combinación de la eficiencia de la AI y la mirada crítica del desarrollador es lo que realmente genera resultados potentes. La AI no reemplaza al humano, lo potencia. Pero &lt;strong&gt;solo si el humano sigue prestando atención&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  En resumen
&lt;/h2&gt;

&lt;p&gt;La AI es perezosa. Y eso no está mal. Porque su pereza, bien entendida, es sinónimo de eficiencia. Pero si queremos que sea una aliada y no una saboteadora silenciosa, necesitamos estar atentos. La supervisión no es una carga: es el complemento natural de esta nueva manera de trabajar.&lt;/p&gt;

&lt;p&gt;¿La AI se salta pasos? A veces sí.&lt;br&gt;&lt;br&gt;
¿Nos obliga a revisar? Siempre.&lt;br&gt;&lt;br&gt;
¿Vale la pena usarla igual? Sin dudas.&lt;/p&gt;




&lt;h2&gt;
  
  
  Reflexión final
&lt;/h2&gt;

&lt;p&gt;Hay un pasaje citado en &lt;strong&gt;Eloquent JavaScript&lt;/strong&gt; que me marcó mucho y que suelo repetir en mis clases. Es de &lt;em&gt;Ellen Ullman&lt;/em&gt;, y dice:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Creemos que estamos haciendo la computadora a nuestra imagen… pero no lo estamos. La computadora no es realmente como nosotros. Es una proyección de una parte muy delgada de nosotros mismos: esa porción dedicada a la lógica, el orden, las reglas y la claridad.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hoy, cuando reflexiono sobre la “pereza” de la inteligencia artificial, estas palabras cobran aún más fuerza. Lo que llamamos “pereza” en los modelos de AI no es más que una versión amplificada de esa parte del ser humano que intenta optimizar, que busca orden, que elimina lo que considera innecesario para lograr un objetivo con el menor esfuerzo posible.&lt;/p&gt;

&lt;p&gt;La AI no es perezosa por descuido. Es perezosa porque está diseñada a imagen y semejanza de nuestra forma más lógica y resolutiva. Porque incluso nosotros, al programar, buscamos siempre esa línea de código menos, ese algoritmo más eficiente, ese truco que nos ahorra tiempo.&lt;/p&gt;

&lt;p&gt;La AI no es un espejo completo de la humanidad. Es un espejo afilado de nuestra lógica. Y nuestra lógica, a veces, también prefiere atajos.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>chatgpt</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Qué es el principio de incertidumbre de un estado en React</title>
      <dc:creator>Josué Oroya</dc:creator>
      <pubDate>Wed, 16 Apr 2025 03:03:15 +0000</pubDate>
      <link>https://dev.to/joshuacba08/que-es-el-principio-de-incertidumbre-de-un-estado-en-react-d35</link>
      <guid>https://dev.to/joshuacba08/que-es-el-principio-de-incertidumbre-de-un-estado-en-react-d35</guid>
      <description>&lt;h2&gt;
  
  
  Principio de incertidumbre de un estado en React
&lt;/h2&gt;

&lt;p&gt;Si has trabajado con React, es probable que hayas tenido problemas con los estados de tus componentes. En este artículo veremos como enfrentar este problema y las distinas formas de solucionarlo.&lt;/p&gt;

&lt;p&gt;Hace poco estuve ayudando a un colega con un problema en su aplicación de React. Estaba trabajando con un componente que debía reproducir un video y pausar la reproducción en un segundo determinado. Al principio uno puede pensar que es un problema sencillo, es decir, tienes un simple estado booleano que indica si el video está en reproducción o no. Sin embargo, luego de probar la aplicación, se dió cuenta que en ocasiones el video no volvía a reproducirse por más lógica que le añadiera, incluso GPT le decía que estaba bien, o añadía más lógica y el problema persistía. Entonces, ¿qué estaba pasando? ¿Por qué no podía hacer que su video se reprodujera nuevamente?&lt;/p&gt;

&lt;p&gt;En ese momento dijo una frase que me hizo pensar:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Lo ideal sería que mi componente funcione o no funcione, pero... ¡funciona a veces y a veces no!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Esto me hizo reflexionar, ya que es verdad, cuando desarrollamos componentes que responden a un estado para definir su comportamiento, pero estos terminan teniendo un comportamiento errático, tendemos a pensar que se trata de un bug pero no diagnosticamos el problema correctamente.&lt;/p&gt;

&lt;p&gt;Si tu código funciona unas veces y otras no, y esto depende de un estado, entonces podemos decir que el estado se encuentra en un (valga la redundancia) estado de incertidumbre. Esto es lo que yo llamo el &lt;strong&gt;principio de incertidumbre de un estado en React&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Ok, quiza esto suene un poco raro, o tan solo pienses que se trata de un bug y ya. Pero ser concientes de que el problema tiene que ver con que el estado se encuentra en un estado de incertidumbre, nos puede ayudar a encontrar la solución.&lt;/p&gt;

&lt;h2&gt;
  
  
  Principio de incertidumbre de un estado en React
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Cuando un componente React se comporta de manera aleatoria ante cambios de estado —funciona a veces y a veces no— estamos frente a un estado en incertidumbre.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Este principio no habla de física cuántica ni del funcionamiento interno de React, sino del momento exacto en que un desarrollador siente que todo está bien en su código, pero el comportamiento no es consistente.&lt;/p&gt;

&lt;p&gt;No hay errores visibles, no hay excepciones, y hasta la lógica parece sólida. Pero sin embargo… el componente falla, y lo hace de forma errática. Reproduce un video unas veces sí y otras no. Cambia una clase CSS a veces sí, otras no. La actualización de un booleano simplemente no sucede o si sucede, no se refleja en la UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Por qué sucede esto?
&lt;/h2&gt;

&lt;p&gt;Ahora que hemos diagnosticado que el problema tiene que ver con un estado en incertidumbre, es hora de ver por qué sucede esto.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. El estado no se actualiza
&lt;/h3&gt;

&lt;p&gt;El primer problema que puede suceder es que el estado no se actualiza. Esto puede suceder por varias razones, pero la más común es que el estado no se actualiza de forma síncrona. Esto significa que cuando llamas a &lt;code&gt;setState&lt;/code&gt;, el nuevo valor del estado no está disponible inmediatamente. En su lugar, React programa una actualización del estado y lo actualiza en un momento posterior. Este es un error muy común sobre todo en principiantes, ya que piensan que el estado se actualiza inmediatamente y no es así.&lt;/p&gt;

&lt;h4&gt;
  
  
  Ejemplo
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isPlaying&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsPlaying&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handlePlay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setIsPlaying&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;¿Está reproduciendo?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isPlaying&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ❌ Siempre muestra: false&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handlePause&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setIsPlaying&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;¿Está reproduciendo?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isPlaying&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ❌ Siempre muestra: true&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, el estado &lt;code&gt;isPlaying&lt;/code&gt; no se actualiza inmediatamente después de llamar a &lt;code&gt;setIsPlaying&lt;/code&gt;. Por lo tanto, cuando intentamos acceder al valor del estado inmediatamente después de actualizarlo, siempre obtendremos el valor anterior.&lt;/p&gt;

&lt;h4&gt;
  
  
  Solución recomendada
&lt;/h4&gt;

&lt;p&gt;La forma correcta de trabajar con el nuevo valor del estado es esperar a que React haga el render y reaccionar a los cambios con un useEffect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isPlaying&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;El video está en reproducción&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// reproducirVideo(); ← tu lógica aquí&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isPlaying&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handlePlay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setIsPlaying&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Si necesitás hacer algo en el momento justo en que el estado cambia, no lo hagas inmediatamente después de setState. Usá useEffect para esperar a que el nuevo valor esté disponible tras el render.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. Funciones externas que afectan al estado sin que te des cuenta
&lt;/h3&gt;

&lt;p&gt;A veces no es el setState el que falla, sino una función externa que modifica el valor o el contexto del estado desde afuera, causando que el comportamiento se vuelva errático.&lt;/p&gt;

&lt;p&gt;Esto puede pasar cuando:&lt;br&gt;
• Tienes lógica compartida en servicios, utilidades o archivos separados.&lt;br&gt;
• Usas referencias (ref) para acceder al DOM o a valores mutables.&lt;br&gt;
• Tienes callbacks que se ejecutan desde fuera del flujo React (como eventos de terceros o listeners manuales).&lt;/p&gt;
&lt;h4&gt;
  
  
  Ejemplo
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isVisible&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsVisible&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;externalController&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onToggle&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setIsVisible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ❗ Pero no sabés que esto se está llamando en otro archivo&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;El estado isVisible cambia “mágicamente”, y tu ni siquiera lo ves en tu componente.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Este es un error común en aplicaciones grandes, donde el estado se comparte entre varios componentes o servicios. Es importante tener cuidado al modificar el estado desde fuera del flujo de React. (Por cierto, este era el problema de mi colega, el video no se reproducía porque había un listener que lo pausaba desde otro archivo y no se daba cuenta).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  Solución recomendada: Encapsular la lógica que modifica el estado
&lt;/h4&gt;

&lt;p&gt;Si una función externa necesita modificar el estado, protege el acceso con una función explícita desde el componente, así controlas cuándo y cómo se cambia:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleToggle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ocultando componente desde controlador externo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;setIsVisible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nx"&gt;externalController&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onToggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handleToggle&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;externalController&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;offToggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handleToggle&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; En este caso, el efecto se encarga de limpiar el listener cuando el componente se desmonta, evitando que el estado quede en un estado de incertidumbre.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Consejo práctico
&lt;/h4&gt;

&lt;p&gt;Si sientes que “el estado cambia solo”, probablemente alguien lo está tocando desde afuera. Audita el código en busca de listeners, servicios o refs que puedan modificarlo por fuera del ciclo de React.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Estado sincronizado con props que nunca se actualiza
&lt;/h3&gt;

&lt;p&gt;A veces inicializamos un estado en base a una prop, pero esperamos que ese estado se actualice automáticamente cuando la prop cambie… y no lo hace.&lt;/p&gt;

&lt;p&gt;Esto pasa mucho cuando el desarrollador copia una prop en un useState y asume que estarán sincronizados para siempre. Spoiler: no lo estarán.&lt;/p&gt;

&lt;h4&gt;
  
  
  Ejemplo
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;initialValue&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si initialValue cambia desde el componente padre, value no cambia, porque useState solo toma la prop una vez al inicio. Esto puede generar inconsistencias difíciles de detectar, especialmente cuando usas formularios, modales, o entradas controladas.&lt;/p&gt;

&lt;h4&gt;
  
  
  Solución recomendada: Sincronizar el estado con useEffect
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;initialValue&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; En este caso, el efecto se encarga de sincronizar el estado con la prop inicial, asegurando que siempre tenga el valor correcto.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💡 Consejo práctico&lt;/strong&gt;&lt;br&gt;
Si estás copiando una prop en un state, preguntate:&lt;br&gt;
“¿Esto debería seguir sincronizado o solo es un valor inicial?”&lt;br&gt;
Si quieres que se mantengan sincronizados, necesitas controlarlo manualmente con useEffect.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Este tipo de errores se manifiestan como: &lt;strong&gt;“mi input no cambia aunque la prop cambió”&lt;/strong&gt;, o “el modal no se actualiza cuando cambio los datos”, y pueden ser muy difíciles de diagnosticar si no conoces este patrón.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusiones
&lt;/h2&gt;

&lt;p&gt;Si has llegado hasta acá, antes que nada quiero agradecerte por dedicarme tu tiempo. Espero que este artículo te esté resultando útil.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;El principio de incertidumbre de un estado en React no es solo una metáfora divertida —es una herramienta mental útil para diagnosticar esos casos donde “el componente funciona a veces y a veces no”.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Muchos de los errores más difíciles en React no se deben a código incorrecto, sino a expectativas incorrectas sobre cómo y cuándo React actualiza el estado.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Aceptar que el estado puede estar en incertidumbre —que no es inmediato, que puede estar desfasado, que otros efectos lo afectan— te permite salir del ciclo de frustración y pasar al modo detective 😎.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Consejo final
&lt;/h3&gt;

&lt;p&gt;La incertidumbre no siempre es un bug. A veces es una señal de que hay una desincronización entre tu lógica y el ciclo de vida de React.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>javascript</category>
      <category>react</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Configurando un proyecto de React para producción</title>
      <dc:creator>Josué Oroya</dc:creator>
      <pubDate>Thu, 24 Oct 2024 21:36:28 +0000</pubDate>
      <link>https://dev.to/joshuacba08/configurando-un-proyecto-de-react-para-produccion-7hb</link>
      <guid>https://dev.to/joshuacba08/configurando-un-proyecto-de-react-para-produccion-7hb</guid>
      <description>&lt;p&gt;Internet está lleno de tutoriales sobre cómo iniciar un proyecto web con React, sin embargo la mayoría de estos tutoriales son para proyectos pequeños o de prueba. En este tutorial, aprenderás cómo las empresas reales configuran sus proyectos de React para producción utilizando las mejores prácticas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requerimientos técnicos
&lt;/h2&gt;

&lt;p&gt;Para seguir este artículo, necesitarás tener instalado las siguientes tecnologías:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js V20.10.0 o superior&lt;/li&gt;
&lt;li&gt;Git v2.43.0 o superior&lt;/li&gt;
&lt;li&gt;Visual Studio Code v1.94.0 o superior&lt;/li&gt;
&lt;li&gt;pnpm&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Estas son las versiones que he utilizado para escribir este artículo, pero es posible que funcione con versiones anteriores no muy antiguas o superiores.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Por qué pnpm?
&lt;/h2&gt;

&lt;p&gt;Quizás la típica frase que oirás decir a la mayoría de los desarrolladores que usamos pnpm es: "pnpm es más rápido que npm y yarn". Pero en mi experiencia trabajando en la industria, la razón más importante para usar pnpm es que este instala las dependencias de forma plana, lo que significa que no instala múltiples versiones de la misma dependencia. Esto ahorra espacio en disco y reduce el tiempo de instalación de las dependencias. Además, evita problemas de compatibilidad entre las dependencias.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creando un nuevo proyecto con Vite
&lt;/h2&gt;

&lt;p&gt;Vite es un nuevo bundler que ha ganado mucha popularidad en la comunidad de React. Vite es mucho más rápido que Create React App y es compatible con TypeScript de forma nativa. Para crear un nuevo proyecto con Vite, simplemente ejecuta el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm create vite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Veremos las siguientes opciones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Project name&lt;/strong&gt;: Nombre del proyecto, para este caso, el proyecto se llamará &lt;code&gt;react-real-world&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Select a framework&lt;/strong&gt;: Selecciona React.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Select a variant&lt;/strong&gt;: Selecciona React con TypeScript.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Una vez que hayas seleccionado todas las opciones, Vite creará un nuevo proyecto de React con TypeScript.&lt;/p&gt;

&lt;p&gt;Acto seguido, ejecuta los siguientes comandos para instalar las dependencias necesarias:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;react-real-world
pnpm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;También abriremos el proyecto en Visual Studio Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;code &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  React con SWC o Babel
&lt;/h2&gt;

&lt;p&gt;Vite es compatible con SWC y Babel. SWC es un compilador de JavaScript extremadamente rápido que es compatible con la mayoría de las características de Babel. Sin embargo, Babel es más popular y tiene una comunidad más grande.&lt;/p&gt;

&lt;p&gt;En lineas generales, los parámetros más importantes para elegir entre SWC y Babel son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Velocidad&lt;/strong&gt;: SWC es mucho más rápido que Babel.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compatibilidad&lt;/strong&gt;: Babel es más compatible con las últimas características de JavaScript.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comunidad&lt;/strong&gt;: Babel tiene una comunidad más grande y es más popular.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Si tu aplicación será muy grande y compleja y necesitas una velocidad de compilación muy rápida en producción, te recomiendo que uses SWC. Si tu aplicación es pequeña o mediana y necesitas una compatibilidad máxima con las últimas características de JavaScript, te recomiendo que uses Babel.&lt;/p&gt;

&lt;p&gt;En todo caso, sería mejor iniciar el proyecto con babel, osea no seleccionar SWC en la creación del proyecto, y luego cambiar a SWC si es necesario, los pasos para hacerlo son muy sencillos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configurando ESLint y Prettier con TypeScript para aplicar las mejores prácticas
&lt;/h2&gt;

&lt;p&gt;Ahora que hemos creado nuestro proyecto de React con TypeScript, es hora de configurar ESLint y Prettier para aplicar las mejores prácticas de codificación. Para ello justificaremos ambas herramientas cuando las estemos configurando.&lt;/p&gt;

&lt;p&gt;Antes que nada vamos a instalar las dependencias necesarias:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; prettier eslint eslint-plugin-react eslint-config-prettier eslint-plugin-jsx-a11y @typescript-eslint/parser @typescript-eslint/eslint-plugin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pnpm instalará lo siguiente:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;prettier&lt;/strong&gt;: Herramienta de formateo de código.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;eslint&lt;/strong&gt;: Herramienta de análisis de código.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;eslint-plugin-react&lt;/strong&gt;: Plugin de ESLint para React.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;eslint-config-prettier&lt;/strong&gt;: Desactiva las reglas de ESLint que pueden entrar en conflicto con Prettier.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;eslint-plugin-jsx-a11y&lt;/strong&gt;: Plugin de ESLint para accesibilidad en JSX.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;@typescript-eslint/parser&lt;/strong&gt;: Parser de TypeScript para ESLint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;@typescript-eslint/eslint-plugin&lt;/strong&gt;: Plugin de ESLint para TypeScript.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;El comando &lt;code&gt;--save-dev&lt;/code&gt; instala las dependencias como dependencias de desarrollo, lo que significa que no se instalarán en producción. Esto es obligatorio ya que de lo contrario las dependencias se instalarán en producción y aumentarán el tamaño de la aplicación.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Configurando Prettier
&lt;/h3&gt;

&lt;p&gt;Prettier es una herramienta de formateo de código que te permite formatear tu código automáticamente. La motivación detrás de Prettier es que no deberías perder tiempo formateando tu código manualmente, sino que deberías dejar que Prettier lo haga por ti automáticamente. De esta forma, todos los miembros del equipo de desarrollo seguirán el mismo estilo de codificación.&lt;/p&gt;

&lt;p&gt;Para configurar Prettier, crearemos un archivo llamdo &lt;code&gt;.prettierrc.json&lt;/code&gt; en la raíz del proyecto con el siguiente contenido:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"trailingComma"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"all"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tabWidth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"printWidth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"semi"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"singleQuote"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jsxSingleQuote"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Configurando la extensión de Prettier en Visual Studio Code
&lt;/h4&gt;

&lt;p&gt;Para que Visual Studio Code formatee automáticamente tu código con Prettier, necesitas instalar la extensión de Prettier. Para ello, abre Visual Studio Code y busca la extensión de Prettier en el Marketplace. Una vez que la hayas instalado, Visual Studio Code formateará automáticamente tu código con Prettier cada vez que guardes un archivo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiz9ycnhwmbncxus0829e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiz9ycnhwmbncxus0829e.png" alt="Prettier extension image" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sin embargo, es necesario configurar Visual Studio Code para que use Prettier como formateador de código por defecto. Para ello, abre el archivo de configuración de Visual Studio Code escribiendo &lt;code&gt;Ctrl + ,&lt;/code&gt; si estás en Windows o &lt;code&gt;Cmd + ,&lt;/code&gt; si estás en macOS o con la ruta &lt;code&gt;Archivo &amp;gt; Preferencias &amp;gt; Configuración&lt;/code&gt; para Windows o &lt;code&gt;Code &amp;gt; Preferencias &amp;gt; Configuración&lt;/code&gt; para macOS.&lt;/p&gt;

&lt;p&gt;Acontinuación, selecciona la pestaña &lt;code&gt;Workspace&lt;/code&gt; o &lt;code&gt;Área de trabajo&lt;/code&gt; y busca la configuración &lt;code&gt;Format On Save&lt;/code&gt;. Asegúrate de que la casilla esté marcada.&lt;/p&gt;

&lt;p&gt;Por último, busca la configuración &lt;code&gt;Default Formatter&lt;/code&gt; y selecciona &lt;code&gt;Prettier - Code formatter&lt;/code&gt;. Esto hará que Visual Studio Code añada una carpeta &lt;code&gt;.vscode&lt;/code&gt; en la raíz del proyecto con un archivo &lt;code&gt;settings.json&lt;/code&gt; que contiene la configuración de Prettier para el proyecto. De esa manera el equipo de desarrollo seguirá el mismo estilo de codificación.&lt;/p&gt;

&lt;h5&gt;
  
  
  .vscode/settings.json
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"editor.formatOnSave"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"editor.defaultFormatter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"esbenp.prettier-vscode"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Implementando el archivo &lt;code&gt;.prettierignore&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;El archivo &lt;code&gt;.prettierignore&lt;/code&gt; es un archivo que le dice a Prettier qué archivos o carpetas debe ignorar al formatear el código. Por ejemplo, si tienes archivos de configuración, archivos de prueba o incluso los de distribución que no quieres formatear, puedes añadirlos al archivo &lt;code&gt;.prettierignore&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Crea un archivo llamado &lt;code&gt;.prettierignore&lt;/code&gt; en la raíz del proyecto con el siguiente contenido:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Ignorar la carpeta dist
dist/

# Ignorar build
build/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por cierto, la carpeta &lt;code&gt;node_modules/&lt;/code&gt; está ignorada por defecto en Prettier, por lo que no es necesario añadirla al archivo &lt;code&gt;.prettierignore&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configurando ESLint
&lt;/h3&gt;

&lt;p&gt;Si bien Prettier se encarga de formatear el código automáticamente, ESLint se encarga de analizar el código en busca de errores y malas prácticas. ESLint es una herramienta muy potente que te permite personalizar las reglas de codificación según tus necesidades, aunque sinceramente recomiendo usar un paquete de reglas ya existente como &lt;code&gt;eslint-config-airbnb&lt;/code&gt; o &lt;code&gt;eslint-config-standard&lt;/code&gt; ya que son en teoría convenciones de codificación que han sido probadas y son utilizadas por la comunidad.&lt;/p&gt;

&lt;p&gt;Por defecto a la fecha Octubre 2024, Vite en su versión 5.4.9 crea un archivo llamado &lt;code&gt;eslint.config.js&lt;/code&gt; con una configuración básica de ESLint. Sin embargo, vamos a modificarlo de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;js&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@eslint/js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;tsEslint&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@typescript-eslint/eslint-plugin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;tsParser&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@typescript-eslint/parser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;prettierConfig&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;eslint-config-prettier&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;jsxA11y&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;eslint-plugin-jsx-a11y&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;reactHooks&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;eslint-plugin-react-hooks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;reactRefresh&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;eslint-plugin-react-refresh&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;globals&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;globals&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;ignores&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dist&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node_modules&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// Archivos y carpetas ignorados&lt;/span&gt;
    &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;**/*.{ts,tsx,js,jsx}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// Archivos a lint&lt;/span&gt;
    &lt;span class="na"&gt;languageOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;ecmaVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;latest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Versión de ECMAScript más reciente&lt;/span&gt;
      &lt;span class="na"&gt;sourceType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;module&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Módulos ES&lt;/span&gt;
      &lt;span class="na"&gt;globals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;globals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Soporte para los globales del navegador&lt;/span&gt;
      &lt;span class="na"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tsParser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Parser para TypeScript&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;linterOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;reportUnusedDisableDirectives&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Detecta directivas deshabilitadas no usadas&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-hooks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;reactHooks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Plugin para React Hooks&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-refresh&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;reactRefresh&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Plugin para React Refresh&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@typescript-eslint&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tsEslint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Plugin para TypeScript&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jsx-a11y&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;jsxA11y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Plugin para accesibilidad en JSX&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;recommended&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Reglas recomendadas de JavaScript&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;tsEslint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;recommended&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Reglas recomendadas de TypeScript&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;reactHooks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;recommended&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Reglas recomendadas de React Hooks&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-refresh/only-export-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;warn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;allowConstantExport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@typescript-eslint/no-unused-vars&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;warn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Advertencia para variables no usadas en TypeScript&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jsx-a11y/no-static-element-interactions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;warn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Accesibilidad para interacciones de elementos estáticos&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;prettierConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Configuración de Prettier añadida directamente&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La configuración propuesta es bastante sólida y sigue prácticas modernas para proyectos de React con TypeScript utilizando ESLint. Vamos a justificar algunas de las decisiones tomadas:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. &lt;strong&gt;Uso de plugins&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;React Hooks y React Refresh&lt;/strong&gt;: Estamos utilizando los plugins correctos para optimizar el comportamiento de React Hooks y asegurar la actualización rápida con React Refresh. Estos son esenciales para una experiencia de desarrollo rápida en entornos de React.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript&lt;/strong&gt;: Usar &lt;code&gt;@typescript-eslint/eslint-plugin&lt;/code&gt; junto con &lt;code&gt;@typescript-eslint/parser&lt;/code&gt; es la forma correcta de integrar TypeScript en ESLint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accesibilidad (&lt;code&gt;jsx-a11y&lt;/code&gt;)&lt;/strong&gt;: Incluir &lt;code&gt;eslint-plugin-jsx-a11y&lt;/code&gt; es una excelente práctica para asegurar que tu aplicación React siga buenas prácticas de accesibilidad.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. &lt;strong&gt;Soporte para Prettier&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Incluir &lt;code&gt;eslint-config-prettier&lt;/code&gt; al final del arreglo es lo correcto. Esto asegura que las reglas de estilo y formato de Prettier no entren en conflicto con las reglas de ESLint, permitiendo que Prettier maneje el formato del código y ESLint se centre en la calidad del código.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3. &lt;strong&gt;Ignorar archivos&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ignores: ['dist', 'node_modules']&lt;/code&gt;&lt;/strong&gt;: Este uso de &lt;code&gt;ignores&lt;/code&gt; es correcto y moderno, ya que &lt;code&gt;.eslintignore&lt;/code&gt; ha sido reemplazado por la propiedad &lt;code&gt;ignores&lt;/code&gt; en las configuraciones planas.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  4. &lt;strong&gt;Configuración de reglas&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Recomendadas&lt;/strong&gt;: Se ha configurado correctamente las reglas recomendadas de JavaScript, TypeScript y React Hooks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reglas personalizadas&lt;/strong&gt;: Las reglas personalizadas como &lt;code&gt;'@typescript-eslint/no-unused-vars': 'warn'&lt;/code&gt; están bien configuradas para evitar que las variables no usadas rompan la compilación, pero sigan mostrando advertencias. También, se añadió reglas para la accesibilidad (&lt;code&gt;'jsx-a11y/no-static-element-interactions': 'warn'&lt;/code&gt;) es una excelente opción para garantizar que los componentes cumplan con los estándares de accesibilidad.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Probando la configuración de ESLint y Prettier
&lt;/h3&gt;

&lt;p&gt;Para probar la configuración de ESLint y Prettier, bastará con ejecutar el siguiente comando:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ESLint&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm eslint &lt;span class="s1"&gt;'./src/**/*.{ts,tsx,js,jsx}'&lt;/span&gt; &lt;span class="nt"&gt;--fix&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Prettier&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm prettier &lt;span class="nt"&gt;--write&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si todo está configurado correctamente, ESLint y Prettier formatearán y analizarán tu código sin errores. Si hay errores, ESLint y Prettier te mostrarán mensajes de error en la consola y te indicarán cómo solucionarlos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Añadiendo scripts de ESLint y Prettier al &lt;code&gt;package.json&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Para facilitar el uso de ESLint y Prettier, añadiremos scripts al archivo &lt;code&gt;package.json&lt;/code&gt; que nos permitirán ejecutar ESLint y Prettier con un solo comando.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pnpm eslint './src/**/*.{ts,tsx,js,jsx}' --fix"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"format"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pnpm prettier --write ."&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Después de añadir los scripts, ahora tenemos que asegurarnos de que estos se ejecuten antes de crear un commit que sería el paso previo a enviar el código a nuestro repositorio remoto y posteriormente a producción. Para ello, vamos a instalar la dependencia &lt;code&gt;husky&lt;/code&gt; que nos permitirá ejecutar scripts antes de realizar un commit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configurando Husky para ejecutar ESLint y Prettier antes de hacer un commit
&lt;/h2&gt;

&lt;p&gt;Husky es una herramienta que te permite ejecutar scripts antes de realizar un commit en Git. Esto es útil para asegurarte de que tu código cumple con las reglas de ESLint y Prettier antes de enviarlo a tu repositorio remoto.&lt;/p&gt;

&lt;p&gt;Para evitar accidentes, podemos configurar &lt;code&gt;Husky&lt;/code&gt; y &lt;code&gt;lint-staged&lt;/code&gt;, que se ejecutan antes de confirmar nuestro código en Git y garantizan que Prettier y ESLint se ejecuten correctamente en el código fuente antes de confirmarlo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inicializar git en el proyecto
&lt;/h3&gt;

&lt;p&gt;Ya que estamos usando Vite, este bundle no inicializa un repositorio git por defecto, por lo que debemos hacerlo manualmente. Para ello, ejecuta el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Instalar Husky y lint-staged
&lt;/h3&gt;

&lt;p&gt;Vamos a instalar las dependencias necesarias:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; husky lint-staged
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configurar Husky y lint-staged
&lt;/h3&gt;

&lt;p&gt;Abre el archivo &lt;code&gt;package.json&lt;/code&gt; y añade las siguientes configuraciones:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"lint-staged"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"*.ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"eslint --fix"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"prettier --write"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"*.tsx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"eslint --fix"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"prettier --write"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esta configuración le dice a &lt;code&gt;lint-staged&lt;/code&gt; que ejecute ESLint y Prettier en los archivos &lt;code&gt;.ts&lt;/code&gt; y &lt;code&gt;.tsx&lt;/code&gt; antes de confirmarlos en Git.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nota: Como puedes ver, estamos separando los archivos &lt;code&gt;.ts&lt;/code&gt; y &lt;code&gt;.tsx&lt;/code&gt; para darle más flexibilidad y granularidad a la configuración. Puedes añadir más extensiones de archivos si lo necesitas. Esto nos permitirá la posibilidad de aplicar reglas específicas y diferentes para cada tipo de archivo. Sin embargo, si deseas aplicar las mismas reglas a todos los archivos, puedes usar &lt;code&gt;*.{ts,tsx}&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Inicializar Husky
&lt;/h4&gt;

&lt;p&gt;Para inicializar Husky, ejecuta el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm &lt;span class="nb"&gt;exec &lt;/span&gt;husky init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Nota: el comando &lt;code&gt;pnpm exec&lt;/code&gt; ejecuta un comando en el contexto de un paquete, en este caso, &lt;code&gt;husky&lt;/code&gt;. Puedes consultar los comandos disponibles en la &lt;a href="https://typicode.github.io/husky/get-started.html" rel="noopener noreferrer"&gt;documentación oficial de Husky&lt;/a&gt; si estás usando npm o yarn.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;El comando anterior creará un archivo llamado &lt;code&gt;.husky/pre-commit&lt;/code&gt; en la raíz del proyecto con el siguiente contenido:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este comando ejecutará los tests antes de confirmar el código en Git. Sin embargo, vamos a modificarlo para que ejecute ESLint y Prettier en su lugar.&lt;/p&gt;

&lt;h4&gt;
  
  
  Modificar el archivo &lt;code&gt;.husky/pre-commit&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Abre el archivo &lt;code&gt;.husky/pre-commit&lt;/code&gt; y modifícalo de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx lint-staged
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este script ejecutará &lt;code&gt;lint-staged&lt;/code&gt; antes de confirmar el código en Git. &lt;code&gt;lint-staged&lt;/code&gt; ejecutará ESLint y Prettier en los archivos &lt;code&gt;.ts&lt;/code&gt; y &lt;code&gt;.tsx&lt;/code&gt; antes de confirmarlos.&lt;/p&gt;

&lt;h4&gt;
  
  
  Asegurarse de que Husky se instale cuando se clone el repositorio
&lt;/h4&gt;

&lt;p&gt;Ya que es probable que en un proyecto real se clone el repositorio en diferentes máquinas, es importante que Husky se instale automáticamente en cada máquina. Para ello, añade el siguiente script al archivo &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prepare"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"husky install"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Bonus: Configurando una convención de commits con Commitlint
&lt;/h2&gt;

&lt;p&gt;Commitlint es una herramienta que te permite configurar una convención de commits en tu proyecto. Esto es útil para asegurarte de que todos los commits sigan un formato específico y sean fáciles de leer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Instalar Commitlint
&lt;/h3&gt;

&lt;p&gt;Vamos a instalar las dependencias necesarias:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm add &lt;span class="nt"&gt;--save-dev&lt;/span&gt; @commitlint/&lt;span class="o"&gt;{&lt;/span&gt;cli,config-conventional&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luego crear un archivo llamado &lt;code&gt;commitlint.config.js&lt;/code&gt; en la raíz del proyecto usando el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"export default { extends: ['@commitlint/config-conventional'] };"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; commitlint.config.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto creará un archivo &lt;code&gt;commitlint.config.js&lt;/code&gt; con la configuración de Commitlint con el siguiente contenido:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;extends&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@commitlint/config-conventional&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configurar Husky para ejecutar Commitlint antes de hacer un commit
&lt;/h3&gt;

&lt;p&gt;Ahora toca configurar Husky para que ejecute Commitlint antes de hacer un commit. Para ello, crearemos un hook llamdo &lt;code&gt;commit-msg&lt;/code&gt; que se ejecutará antes de confirmar el mensaje del commit. Usaremos el siguiente comando para crear el hook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"npx --no -- commitlint --edit &lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="s2"&gt;1"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .husky/commit-msg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este comando crear un archivo &lt;code&gt;.husky/commit-msg&lt;/code&gt; en la raíz del proyecto con el siguiente contenido:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;--no&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; commitlint &lt;span class="nt"&gt;--edit&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este script ejecutará Commitlint antes de confirmar el mensaje del commit en Git. Commitlint comprobará que el mensaje del commit siga la convención de commits configurada en el archivo &lt;code&gt;commitlint.config.js&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nota: Esta configuración está disponible para la version 9 de Husky, si estás usando una versión anterior, puedes consultar la &lt;a href="https://typicode.github.io/husky/get-started.html" rel="noopener noreferrer"&gt;documentación oficial de Husky&lt;/a&gt; para obtener más información.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Convención de commits
&lt;/h3&gt;

&lt;p&gt;La convención de commits que estamos utilizando es la convención convencional de Angular. Esta convención es muy popular y es utilizada por muchas empresas y proyectos de código abierto. A continuación mencionaremos algunos ejemplos de commits que siguen esta convención:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;feat&lt;/code&gt;: Nueva funcionalidad.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fix&lt;/code&gt;: Corrección de errores.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docs&lt;/code&gt;: Cambios en la documentación.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;style&lt;/code&gt;: Cambios que no afectan el código (espacios en blanco, formato, etc.).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;refactor&lt;/code&gt;: Cambios en el código que no corrigen errores ni añaden funcionalidades.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;perf&lt;/code&gt;: Cambios en el código que mejoran el rendimiento.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;test&lt;/code&gt;: Añadir o modificar pruebas.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;chore&lt;/code&gt;: Cambios en el proceso de construcción o herramientas auxiliares y bibliotecas.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;revert&lt;/code&gt;: Revertir un commit anterior.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ci&lt;/code&gt;: Cambios en la configuración de CI/CD.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;build&lt;/code&gt;: Cambios en la configuración de construcción.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Si intentamos hacer un commit que no siga esta convención, Commitlint nos mostrará un mensaje de error y no nos permitirá confirmar el código en Git como se muestra en la siguiente imagen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flxsn07w85b4t3d5q5l4d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flxsn07w85b4t3d5q5l4d.png" alt="Image console" width="800" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para corregir el error, simplemente debemos seguir la convención de commits y volver a intentar hacer el commit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"docs: document for the project"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Link al repositorio remoto
&lt;/h2&gt;

&lt;p&gt;Puedes ver el resultado final haciendo clic en el siguiente link:&lt;br&gt;
&lt;a href="https://github.com/joshuacba08/react-real-world" rel="noopener noreferrer"&gt;Repositorio remoto&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusiones
&lt;/h2&gt;

&lt;p&gt;En este artículo, hemos aprendido cómo configurar un proyecto de React para producción utilizando las mejores prácticas. Hemos configurado Prettier y ESLint para aplicar las mejores prácticas de codificación, Husky y lint-staged para ejecutar ESLint y Prettier antes de hacer un commit, y Commitlint para configurar una convención de commits en nuestro proyecto.&lt;/p&gt;

&lt;p&gt;Espero que este artículo te haya sido útil y te haya ayudado a configurar tu proyecto de React para producción. Si tienes alguna pregunta o sugerencia, no dudes en dejar un comentario.&lt;/p&gt;

</description>
      <category>react</category>
      <category>eslint</category>
      <category>husky</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Entendiendo la metodología BEM</title>
      <dc:creator>Josué Oroya</dc:creator>
      <pubDate>Sat, 18 Feb 2023 18:08:25 +0000</pubDate>
      <link>https://dev.to/joshuacba08/entendiendo-la-metodologia-bem-2n2c</link>
      <guid>https://dev.to/joshuacba08/entendiendo-la-metodologia-bem-2n2c</guid>
      <description>&lt;p&gt;Ya sea durante nuestro aprendizaje o en la misma práctica laboral es probable que nos hallamos encontrado con un problema a la hora de nombrar nuestras clases de css. En este artículo conoceremos la metodología más usada para nombrar nuestras clases, BEM.&lt;/p&gt;

&lt;p&gt;Con proyectos muy pequeños, asignar clases a las etiquetas de html suele ser un trabajo sencillo, y es que no tenemos que pensar tanto a la hora de nombrarlas, sin embargo, cuando nuestro proyecto escala empezamos a notar cierta dificultad e inconsistencia con las clases que vamos nombrando. Es por eso que es muy común ver un HTML de la siguiente manera.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0o5phwl5tiemn9zmk9ho.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0o5phwl5tiemn9zmk9ho.png" alt="Modelo de barra de navegación" width="800" height="62"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;header&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"box-top"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
        &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://res.cloudinary.com/ionicimagesbank/image/upload/v1676553696/material/tutorials/Sample_Logo_mvdjix.png"&lt;/span&gt;
        &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"logo"&lt;/span&gt;
      &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;nav&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"element-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;features&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"element-2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;pricing&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"element-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;community&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"element-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;support&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn-register"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;register&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este es un pequeño ejemplo del HTML correspondiente al diseño de una barra de navegación, además previamente se puede apreciar una imagen previa. &lt;/p&gt;

&lt;p&gt;Como se puede apreciar, hay muchas cosas que se podrían mejorar pero quisiera enfocarme solo en la problemática que viene después. El elemento &lt;code&gt;&amp;lt;li class='elemento-1'&amp;gt;&lt;/code&gt; y los demás están definidos como elementos de algo, es decir como los elementos de &lt;strong&gt;list&lt;/strong&gt;, el problema surge si quiero tener una lista de elementos de otra cosa, ¿Podré usar &lt;code&gt;element-1&lt;/code&gt; ? La respuesta es un sí a medias, lo podré usar siempre y cuando en el css combine selectores, porque de lo contrario tendré elementos de distintos tipos pero con clases nombradas igual. &lt;/p&gt;

&lt;h2&gt;
  
  
  Metodología BEM
&lt;/h2&gt;

&lt;h5&gt;
  
  
  &lt;strong&gt;&lt;em&gt;(Block Element Modifier)&lt;/em&gt;&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;Esta metodología tiene un enfoque basado en componentes para el desarrollo web. Básicamente, se trata de dividir en &lt;strong&gt;bloques independientes&lt;/strong&gt; cada subdivisión de nuestro layout.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fccswpp14egeh7s231zlz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fccswpp14egeh7s231zlz.png" alt="digrama de BEM" width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Bloque:
&lt;/h3&gt;

&lt;p&gt;Contenedor o contexto donde se encuentra un elemento. Conforma la raíz de una clase. El nombre del bloque describe su propósito, es por eso que para nombrar esta clase debemos hacernos la siguiente pregunta: &lt;strong&gt;&lt;em&gt;¿Qué es?&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;nav&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"links-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;a&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;a&amp;gt;&lt;/span&gt;Login&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;a&amp;gt;&lt;/span&gt;Register&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como se ve en la imagen anterior, tengo una etiqueta &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt; la cual tiene como fin contener un numero de links de navegación, haciendo este ejercicio, el nombre elegido sería &lt;em&gt;links-container&lt;/em&gt; o &lt;em&gt;contenedor de links&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Elemento
&lt;/h3&gt;

&lt;p&gt;Es una pieza del bloque. Se puede decir que el bloque es el contenedor principal y los elementos son las piezas que lo conforman. Este concepto de elemento no puede aplicarse sin antes haber definido un bloque que lo contenga. &lt;br&gt;
Al igual que el bloque, el nombre del elemento también describe su propósito. Es por ello que también nos haremos la siguiente pregunta: &lt;strong&gt;&lt;em&gt;¿Qué es?&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;nav&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"links-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"links-container__link"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"links-container__link"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Login&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"links-container__link"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Register&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para construir el nombre de la clase para un elemento será necesario anteponer el nombre del bloque seguido de dos guiones bajo, es decir:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;nombre-del-bloque&lt;/em&gt;__&lt;strong&gt;nombre-del-elemento&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Modificador
&lt;/h3&gt;

&lt;p&gt;Un modificador define la apariencia, estado o comportamiento de un bloque o un elemento. Como un ejemplo puntual, podríamos tener un contenedor de links: Home | Login | Register &lt;br&gt;
Es probable que estos tres elementos, tengan que compartir el mismo estilo pero en el caso del &lt;em&gt;register&lt;/em&gt;, este tendría una leve variación, ya que al inducir a una acción como &lt;em&gt;registrarse&lt;/em&gt; será necesario hacerlo más llamativo. Por lo tanto, para nombrar dicha clase tendremos que preguntarnos: &lt;strong&gt;&lt;em&gt;¿Cómo se ve?&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;nav&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"links-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"links-container__link"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"links-container__link"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Login&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"links-container__link links-container__link--red"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Register&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para la construcción del nombre de esta clase tendremos que anteponer el nombre del bloque seguido de dos guiones bajo, el nombre del bloque seguido de dos guiones del medio y por último el nombre de nuestra clase. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;nombre-del-bloque__nombre-del-elemento&lt;/em&gt;--&lt;strong&gt;nombre-del-modificador&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fju3htagfyn97shlp39cj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fju3htagfyn97shlp39cj.png" alt="Esquema completo de BEM" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusión:
&lt;/h3&gt;

&lt;p&gt;La metodología BEM nos abre un sin fin de posibilidades para nombrar clases de una manera consecuente y ordenada. Además, debido a su combinación de palabras, también nos proveerá de clases con más especificidad si es que además combinamos selectores en el css. &lt;/p&gt;

</description>
      <category>html</category>
      <category>css</category>
      <category>frontend</category>
      <category>spanish</category>
    </item>
    <item>
      <title>VueJS - Día 01</title>
      <dc:creator>Josué Oroya</dc:creator>
      <pubDate>Fri, 02 Sep 2022 00:13:56 +0000</pubDate>
      <link>https://dev.to/joshuacba08/vuejs-dia-01-15jb</link>
      <guid>https://dev.to/joshuacba08/vuejs-dia-01-15jb</guid>
      <description>&lt;p&gt;[toc]&lt;br&gt;
Bienvenidos a nuestro día 1 con VueJS. Para empezar, vamos a considerar los siguientes requerimientos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node JS&lt;/li&gt;
&lt;li&gt;npm&lt;/li&gt;
&lt;li&gt;git&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Creación de un proyecto en VueJS
&lt;/h2&gt;

&lt;p&gt;Podremos instalar y crear un nuevo proyecto en VueJS desde la página oficial: &lt;a href="https://vuejs.org" rel="noopener noreferrer"&gt;https://vuejs.org&lt;/a&gt; Entonces usaremos el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init vue@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Al correr este comando vamos a crear un nuevo proyecto en VueJS, por lo que veremos en nuestra consola la siguiente interfaz:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;✔ Project name: … &amp;lt;your-project-name&amp;gt;
✔ Add TypeScript? … No / Yes
✔ Add JSX Support? … No / Yes
✔ Add Vue Router &lt;span class="k"&gt;for &lt;/span&gt;Single Page Application development? … No / Yes
✔ Add Pinia &lt;span class="k"&gt;for &lt;/span&gt;state management? … No / Yes
✔ Add Vitest &lt;span class="k"&gt;for &lt;/span&gt;Unit testing? … No / Yes
✔ Add Cypress &lt;span class="k"&gt;for &lt;/span&gt;both Unit and End-to-End testing? … No / Yes
✔ Add ESLint &lt;span class="k"&gt;for &lt;/span&gt;code quality? … No / Yes
✔ Add Prettier &lt;span class="k"&gt;for &lt;/span&gt;code formatting? … No / Yes

Scaffolding project &lt;span class="k"&gt;in&lt;/span&gt; ./&amp;lt;your-project-name&amp;gt;...
Done.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si no estamos seguros de alguna configuración, basta con elegir &lt;strong&gt;NO&lt;/strong&gt; y continuar con la siguiente configuración. Más adelante podremos incluir lo que nos haga falta a nuestro proyecto.&lt;/p&gt;

&lt;p&gt;Veremos que se creará una carpeta con el nombre de nuestro proyecto en VueJS, por lo cual será necesario ingresar e iniciar nuestro proyecto mediante los siguientes comandos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &amp;lt;your-project-name&amp;gt;
npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aún no estamos en condiciones de realizar un build de nuestro proyecto, pero aún así dejo el comando para hacer el build de nuestra aplicación:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Usando la CLI de VueJS
&lt;/h2&gt;

&lt;p&gt;Además de las configuraciones mencionadas anteriormente, podemos hacer uso del CLI de VueJS, un CLI significa "interfaz de línea de comandos", y es una herramienta sumamente importante a la hora de automatizar la creación y actualización de proyectos con un determinado framework. &lt;/p&gt;

&lt;p&gt;Podemos instalar nuestra CLI de VueJS desde su página oficial: &lt;a href="https://cli.vuejs.org" rel="noopener noreferrer"&gt;https://cli.vuejs.org&lt;/a&gt; En todo caso, usaremos el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @vue/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Una vez que hayamos instalado el CLI, podremos iniciar un nuevo proyecto en VueJS con el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vue create 01-first-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lo que veremos a continuación es que el CLI nos proveerá de tres opciones para iniciar nuestro proyecto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Vue CLI v5.0.8
? Please pick a preset:
  Default &lt;span class="o"&gt;([&lt;/span&gt;Vue 3] babel, eslint&lt;span class="o"&gt;)&lt;/span&gt;
  Default &lt;span class="o"&gt;([&lt;/span&gt;Vue 2] babel, eslint&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Manually &lt;span class="k"&gt;select &lt;/span&gt;features
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Las dos primeras son pre configuraciones para trabajar con Vue 2 o Vue 3, ambas son versiones de VueJS muy usadas. Mientras escribo este material, Vue 2 continúa siendo la versión más usada, sin embargo en un futuro no muy lejano primará Vue 3 en la mayoría de proyectos con este framework. &lt;/p&gt;

&lt;p&gt;Para esta instancia usaremos la opción 3 que es la de seleccionar las características de forma manual.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Vue CLI v5.0.8
? Please pick a preset: Manually &lt;span class="k"&gt;select &lt;/span&gt;features
? Check the features needed &lt;span class="k"&gt;for &lt;/span&gt;your project: &lt;span class="o"&gt;(&lt;/span&gt;Press &amp;lt;space&amp;gt; to &lt;span class="k"&gt;select&lt;/span&gt;, &amp;lt;a&amp;gt; to toggle all, &amp;lt;i&amp;gt; to invert selection,
and &amp;lt;enter&amp;gt; to proceed&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; Babel
 &lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt; TypeScript
 &lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt; Progressive Web App &lt;span class="o"&gt;(&lt;/span&gt;PWA&lt;span class="o"&gt;)&lt;/span&gt; Support
 &lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt; Router
 &lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt; Vuex
 &lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt; CSS Pre-processors
 &lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt; Linter / Formatter
 &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; Unit Testing
 &lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt; E2E Testing

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por el momento solo elegiremos Babel y Unit Testing. &lt;strong&gt;&lt;em&gt;La selección se hace presionando "space"&lt;/em&gt;&lt;/strong&gt; . &lt;br&gt;
Continuaremos presionando &lt;strong&gt;"Enter"&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Vue CLI v5.0.8
? Please pick a preset: Manually &lt;span class="k"&gt;select &lt;/span&gt;features
? Check the features needed &lt;span class="k"&gt;for &lt;/span&gt;your project: Babel, Unit
? Choose a version of Vue.js that you want to start the project with
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 3.x
  2.x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A continuación elegiremos la versión 3 de Vue JS y como herramientas para test Jest&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Vue CLI v5.0.8
? Please pick a preset: Manually &lt;span class="k"&gt;select &lt;/span&gt;features
? Check the features needed &lt;span class="k"&gt;for &lt;/span&gt;your project: Babel, Unit
? Choose a version of Vue.js that you want to start the project with 3.x
? Pick a unit testing solution: &lt;span class="o"&gt;(&lt;/span&gt;Use arrow keys&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Jest
  Mocha + Chai
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por último, el CLI nos preguntará si queremos usar un archivo dedicado para guardar esta configuración o si preferimos usar el package.json&lt;br&gt;&lt;br&gt;
Elegiremos usar un &lt;strong&gt;archivo dedicado&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;¡Listo! Ya tenemos nuestro primer proyecto en VueJS creado con el CLI. Ahora vamos a abrirlo y para eso al igual que el ejemplo anterior usaremos los siguientes comandos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;01-first-app
npm run serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>vue</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Dos formas de crear un proyecto con React JS</title>
      <dc:creator>Josué Oroya</dc:creator>
      <pubDate>Thu, 01 Sep 2022 23:10:10 +0000</pubDate>
      <link>https://dev.to/joshuacba08/dos-formas-de-crear-un-proyecto-con-react-js-4oi</link>
      <guid>https://dev.to/joshuacba08/dos-formas-de-crear-un-proyecto-con-react-js-4oi</guid>
      <description>&lt;p&gt;Existen muchas formas de crear una aplicación con React JS, sin embargo quisiera compartir la forma más usada y la forma que deberíamos probar usar a partir de ahora. &lt;/p&gt;

&lt;p&gt;Hace algunos años la única manera de crear un proyecto con React JS era crear el proyecto desde cero, archivo por archivo a través de la configuración de webpack, lo cual sinceramente es una locura, aunque como punto a favor, se tenía un control total.&lt;/p&gt;

&lt;p&gt;Hoy en día la manera más sencilla de crear un proyecto de react js es usando el comando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app nombre-de-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y es que este comando hace algo tan increible como crear una aplicación de react js desde cero, al cual le podremos asignar un nombre en lugar de "nombre-de-app".&lt;/p&gt;

&lt;p&gt;Pero no todo acaba ahí, hace poco se ha sumando una herramienta muy buena e increíblemente rápída llamada Vite JS. Los invito a ver este video 😉&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/OyQ76APYPtI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>react</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>React JS &amp; Tailwindcss - 01-Instalación</title>
      <dc:creator>Josué Oroya</dc:creator>
      <pubDate>Thu, 01 Sep 2022 23:05:39 +0000</pubDate>
      <link>https://dev.to/joshuacba08/react-js-tailwindcss-01-instalacion-3k8l</link>
      <guid>https://dev.to/joshuacba08/react-js-tailwindcss-01-instalacion-3k8l</guid>
      <description>&lt;p&gt;Instala Tailwindcss en tu proyecto de React JS y usa uno de los mejores frameworks para estilar.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/kHhKxX3IUiw"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>style</category>
      <category>tailwindcss</category>
      <category>react</category>
    </item>
    <item>
      <title>React JS - Clase 2</title>
      <dc:creator>Josué Oroya</dc:creator>
      <pubDate>Wed, 27 Jul 2022 13:39:00 +0000</pubDate>
      <link>https://dev.to/joshuacba08/react-js-clase-2-50eh</link>
      <guid>https://dev.to/joshuacba08/react-js-clase-2-50eh</guid>
      <description>&lt;p&gt;Hola a todas y todos. He creado este foro en dev.to para atender las consultas que puedan surgir respecto al curso que dicto actualmente. Debido a que es un foro público, por favor no compartan información sensible como datos personales, etc. Pueden dejarme sus comentarios debajo de esta publicación y con gusto les estaré respondiendo a la brevedad. &lt;/p&gt;

&lt;p&gt;Elegí dev.to ya que más allá de ser gratuito, también podrán acceder a muchos post de la comunidad de desarrolladores, además podrán escribir código acá o adjuntar imágenes para realizar sus consultas. &lt;/p&gt;

&lt;p&gt;Cualquier sugerencia que tengan es bienvenida 😊&lt;/p&gt;

&lt;p&gt;Les dejo el componente que creamos hoy:&lt;/p&gt;

&lt;h2&gt;
  
  
  Count.jsx
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./styles/Count.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;initial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stock&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initial&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Se ejecuta addCount&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;count-container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;count-container__count&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;count-container__controls&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; 
                    &lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="nx"&gt;initial&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;controls__button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                    &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;addCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}}&lt;/span&gt;               
                &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="o"&gt;-&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;
                    &lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="nx"&gt;stock&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; 
                    &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;controls__button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                    &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;addCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}}&lt;/span&gt;
                &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="o"&gt;+&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Count.css
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.count-container&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;400px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.count-container&lt;/span&gt; &lt;span class="nc"&gt;.count-container__count&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.count-container&lt;/span&gt; &lt;span class="nc"&gt;.count-container__controls&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.count-container&lt;/span&gt; &lt;span class="nc"&gt;.count-container__controls&lt;/span&gt; &lt;span class="nc"&gt;.controls__button&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;4rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;9px&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si bien les dije que vamos a crear un repositorio de github, se me ocurrió que podemos ver cómo subir nuestro repo en github para la siguiente clase, así que lo haremos la próxima semana. &lt;/p&gt;

&lt;p&gt;Acá les dejor un ejemplo que hice para el contador de un e-Commerce&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://stackblitz.com/edit/react-zsrflx?embed=1&amp;amp;file=src/components/ItemCount.jsx" width="100%" height="500"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Tip CSS: Usando "position" para centrar un elemento dentro de su contenedor</title>
      <dc:creator>Josué Oroya</dc:creator>
      <pubDate>Mon, 19 Jul 2021 12:38:16 +0000</pubDate>
      <link>https://dev.to/joshuacba08/tip-css-usando-position-para-centrar-un-elemento-dentro-de-su-contenedor-42d7</link>
      <guid>https://dev.to/joshuacba08/tip-css-usando-position-para-centrar-un-elemento-dentro-de-su-contenedor-42d7</guid>
      <description>&lt;p&gt;Post en desarrollo&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Usa variables en CSS sin dependencias</title>
      <dc:creator>Josué Oroya</dc:creator>
      <pubDate>Mon, 19 Jul 2021 12:25:16 +0000</pubDate>
      <link>https://dev.to/joshuacba08/usa-variables-en-css-sin-dependencias-g22</link>
      <guid>https://dev.to/joshuacba08/usa-variables-en-css-sin-dependencias-g22</guid>
      <description>&lt;p&gt;Esta es una prueba inicial... &lt;br&gt;
Nota en desarrollo.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
