👨🏼‍💻

khriztianmoreno's Blog

Inicio Etiquetas Acerca |

Posts with tag react

Stack Tecnológico 2025

2025-01-03
reactweb-developmentjavascript

El ecosistema React es un paisaje dinámico de tecnologías en constante evolución. Este artículo profundiza en un potente stack tecnológico para construir aplicaciones full-stack en 2025, permitiéndote dar vida a tu propio producto (como un SaaS) o a su Producto Mínimo Viable (MVP).Como desarrollador web Fullstack experimentado, he pasado años perfeccionando mi enfoque. Las reevaluaciones anuales de los stack tecnológicos son cruciales para equilibrar las tendencias de vanguardia con la estabilidad y la mantenibilidad de los proyectos a largo plazo.Mi última experiencia laboral, que culminó en noviembre de 2024, me ha proporcionado valiosos comentarios. Aunque estoy satisfecho con el stack tecnológico inicial, la retrospectiva ofrece valiosas lecciones para futuros proyectos.Embarquémonos en este viaje de descubrimiento y exploremos las apasionantes posibilidades que aguardan en esta concisa pero potente selección.React como framework full-stackRemix.jsRemix.js es un framework web full-stack que prioriza la experiencia del desarrollador y aprovecha los fundamentos web para crear aplicaciones web rápidas, resilientes y amigables para el usuario.Características Clave:Carga y Obtención de Datos: Remix simplifica la obtención de datos con cargadores y acciones integradas. Los loaders obtienen datos antes de renderizar una ruta, mientras que las acciones manejan envíos de formularios y otros efectos secundarios.Enrutamiento Basado en el Sistema de Archivos: Las rutas se definen como archivos dentro del sistema de archivos de tu proyecto, haciendo que la estructura de enrutamiento sea intuitiva y fácil de entender.Renderizado del Lado del Servidor (SSR): Remix sobresale en SSR, proporcionando un excelente SEO y tiempos de carga iniciales más rápidos.Transmisión de Datos: Remix puede transmitir datos al cliente, mejorando el rendimiento percibido y la experiencia del usuario.Manejo de Formularios: El manejo de formularios integrado simplifica tareas comunes como la validación, el envío y el manejo de errores.Pruebas: Remix fomenta las pruebas a varios niveles, incluyendo pruebas unitarias, de integración y de extremo a extremo.Flexibilidad: Remix se puede desplegar en varios entornos, incluyendo servidores Node.js y plataformas de computación en el borde como Cloudflare Workers.Beneficios de Usar Remix:Mejor Rendimiento: SSR y la transmisión de datos contribuyen a tiempos de carga más rápidos y una experiencia de usuario más fluida.Mejor Experiencia del Desarrollador: El enfoque de Remix en la experiencia del desarrollador lo hace agradable de usar, gracias a su enrutamiento intuitivo, mecanismos de obtención de datos y características integradas.Flexibilidad y Escalabilidad: Remix se puede desplegar en varios entornos, haciéndolo adaptable a diferentes necesidades de proyectos.Comunidad y Ecosistema Sólidos: Remix tiene una comunidad en crecimiento y un ecosistema de apoyo con varios recursos y herramientas disponibles.En esencia, Remix.js ofrece un enfoque moderno y eficiente para el desarrollo web, empoderando a los desarrolladores para construir aplicaciones de alta calidad, de alto rendimiento y centradas en el usuario.Astro¿Considerando una landing page dedicada? ¡Astro brilla para esta tarea!Mientras que Remix.js sobresale en aplicaciones monolíticas que sirven tanto contenido estático como dinámico, Astro ofrece una alternativa convincente específicamente para crear landing pages excepcionales. Aquí está el porqué Astro podría ser la elección perfecta:Características Clave:Rendimiento Ultra-Rápido: Astro prioriza la velocidad, entregando landing pages rapidísimas que mantienen a los visitantes comprometidos.Enrutamiento Intuitivo Basado en Archivos: Similar a Remix, Astro aprovecha un sistema de enrutamiento basado en archivos, haciendo que sea fácil estructurar y gestionar el contenido de tu landing page.Desarrollo Basado en Componentes: Construye componentes reutilizables para un proceso de desarrollo optimizado y un diseño consistente en toda tu landing page.Integración con Múltiples Frameworks: Astro se integra sin problemas con frameworks populares como React, Vue y Svelte, permitiéndote aprovechar tus habilidades y preferencias existentes.Soporte para Sistemas de Gestión de Contenidos (CMS) Headless: Astro se lleva bien con varias soluciones CMS headless, permitiendo una gestión flexible del contenido de tu landing page.Beneficios de Usar Astro para Páginas de AterrizajeEnfoque en la Experiencia del Desarrollador: La sintaxis limpia de Astro y su estructura basada en archivos simplifican el desarrollo, permitiéndote concentrarte en crear una landing page impactante.Prototipado Rápido: La velocidad de Astro lo hace ideal para el prototipado rápido y la iteración en el diseño de tu landing page.Optimización SEO: Astro genera HTML limpio y bien estructurado, contribuyendo a una fuerte Optimización para Motores de Búsqueda (SEO) para tu landing page.Tiempos de Construcción Reducidos: Las construcciones incrementales de Astro minimizan los tiempos de construcción, permitiendo ciclos de desarrollo más rápidos.Al aprovechar las fortalezas de Astro, puedes crear una landing page de alto rendimiento y amigable para el desarrollador que capture leads y alimente el crecimiento de tu SaaS, todo mientras ahorras tiempo valioso para enfocarte en el desarrollo del producto principal dentro de tu aplicación Remix/Next.Server ComponentsImagina que estás construyendo una casa. Los Componentes del Servidor son como los trabajadores de construcción que manejan las tareas pesadas y especializadas. En lugar de hacer todo dentro de tu casa (el navegador), estos componentes trabajan afuera, en el servidor.¿Qué hacen?Obtener materiales: Recuperan datos de una base de datos o API, como ir a buscar ladrillos para construir una pared.Hacer cálculos complejos: Realizan operaciones matemáticas o lógicas complicadas, como calcular el área de una habitación.Proteger tu casa: Manejan tareas de seguridad, como verificar si alguien tiene permiso para entrar.¿Por qué son útiles?Tu casa se construye más rápido: Al hacer parte del trabajo en el servidor, tu sitio web carga más rápido para los visitantes.Tu casa es más segura: Los datos sensibles se manejan en un lugar más seguro, fuera del alcance de los intrusos.Puedes enfocarte en la decoración: Los componentes del servidor manejan el trabajo pesado, para que puedas enfocarte en hacer que tu sitio web se vea bien y funcione bien.Server FunctionsPiensa en tu casa teniendo un sistema de intercomunicación. Las Funciones del Servidor son como usar ese intercomunicador para pedirle a un trabajador afuera de la casa que haga algo.¿Cómo funcionan?Tú (tu componente React) le dices al trabajador (la función del servidor) qué hacer, como "por favor trae más ladrillos".El trabajador hace la tarea y te da el resultado.¿Por qué son útiles?Es muy fácil comunicarse: No tienes que preocuparte por los detalles técnicos de enviar y recibir mensajes.Puedes hacer muchas cosas: Puedes pedirle a la función del servidor que haga casi cualquier cosa que un componente del servidor pueda hacer.Server ActionsImagina que tienes una lista de comandos predefinidos para tu intercomunicador. Las Acciones del Servidor son como esos comandos.¿Qué son?Son funciones del servidor diseñadas para realizar tareas específicas, como enviar un formulario o actualizar una base de datos.¿Por qué son útiles?Son fáciles de usar: Ya están configuradas para hacer algo específico, por lo que no tienes que escribir mucho código.Hay muchas bibliotecas que te ayudan: Hay bibliotecas como next-safe-actions y zsa que te proporcionan acciones del servidor predefinidas para tareas comunes.Gestión de Estado en ReactZustandZustand es una biblioteca de gestión de estado ligera y flexible para aplicaciones React. Ofrece una API simple e intuitiva para gestionar el estado global y local, lo que la convierte en una excelente opción para proyectos de todos los tamaños.Características Clave:API Minimalista: Zustand cuenta con una API concisa y fácil de aprender con un código boilerplate mínimo.Orientado al Rendimiento: Zustand está diseñado para un rendimiento óptimo, con actualizaciones de estado eficientes y una sobrecarga mínima.Flexible: Ofrece un enfoque flexible y modular para la gestión de estado, permitiéndote crear y gestionar múltiples stores según sea necesario.Fácil de Aprender: La API simple y la documentación clara hacen que Zustand sea fácil de aprender e integrar en tus proyectos React.import create from "zustand"; const useStore = create((set) => ({ count: 0, increment: () => set((state) => ({ count: state.count + 1 })), })); function Counter() { const count = useStore((state) => state.count); const increment = useStore((state) => state.increment); return <button onClick={increment}>Count: {count}</button>; }RecoilRecoil.js es una biblioteca de gestión de estado para aplicaciones React que proporciona un enfoque más granular y flexible para gestionar el estado compartido en comparación con métodos tradicionales como Context API. Ofrece un gráfico de flujo de datos único que te permite crear estructuras de estado complejas y derivar nuevo estado a partir de los existentes.Conceptos Clave:Átomos: Son las unidades fundamentales de estado en Recoil. Los átomos son independientes y pueden ser suscritos por múltiples componentes. Proporcionan una forma de almacenar y compartir valores simples.Selectores: Los selectores son funciones puras que derivan nuevo estado a partir de átomos existentes u otros selectores. Permiten crear estructuras de estado complejas y realizar cálculos sobre la marcha.RecoilRoot: Este componente es la raíz de tu aplicación Recoil. Proporciona el contexto para todos los átomos y selectores de Recoil.Suscripciones: Los componentes se suscriben a átomos o selectores para recibir actualizaciones cuando el estado cambia. Recoil utiliza mecanismos eficientes para asegurar que los componentes solo se vuelvan a renderizar cuando los datos de los que dependen realmente han cambiado.Características Avanzadas:Valores Asíncronos: Recoil soporta valores asíncronos, permitiéndote obtener datos de APIs y gestionar estados de carga.Persistencia: Puedes persistir el estado de Recoil en el almacenamiento local u otros mecanismos de almacenamiento para restaurarlo en cargas de página posteriores.Depuración con Viaje en el Tiempo: Recoil proporciona herramientas para la depuración con viaje en el tiempo, permitiéndote inspeccionar y retroceder cambios de estado.Hooks Personalizados: Puedes crear hooks personalizados para encapsular lógica compleja de gestión de estado.import { atom, selector, useRecoilState, useRecoilValue } from "recoil"; // Atom for user data (fetched asynchronously) const userDataAtom = atom({ key: "userData", default: null, effects_UNSTABLE: [ ({ setSelf }) => { // Fetch user data from API and set it }, ], }); // Selector to extract the user's name const userNameSelector = selector({ key: "userName", get: ({ get }) => { const userData = get(userDataAtom); return userData?.name || "Guest"; }, }); function UserProfile() { const userName = useRecoilValue(userNameSelector); return <div>Hello, {userName}!</div>; }Estilos CSS en ReactTailwind CSSRevolucionario para el Desarrollo RápidoAunque las opiniones sobre Tailwind CSS varían dentro de la comunidad de desarrolladores, creo firmemente que actualmente es la solución más efectiva para el desarrollo rápido de productos y el mantenimiento a largo plazo de CSS.Basado en mi propia experiencia y en los comentarios de muchos compañeros de trabajo, Tailwind ofrece varias ventajas clave:Prototipado Rápido: El enfoque de utilidades primero de Tailwind permite a los desarrolladores construir y estilizar rápidamente elementos de la UI sin escribir clases CSS personalizadas. Esto acelera significativamente el proceso de prototipado e iteración.Estilo Consistente: Tailwind proporciona un conjunto predefinido de clases de utilidad, asegurando un estilo consistente en todo tu proyecto. Esto elimina la necesidad de reinventar constantemente la rueda y ayuda a mantener un sistema de diseño cohesivo.Mejor Experiencia del Desarrollador: La sintaxis intuitiva de Tailwind y las características de autocompletado en los editores de código modernos mejoran la experiencia del desarrollador, haciendo que escribir y mantener CSS sea más rápido y agradable.Reducción del Tamaño del Archivo CSS: Al aprovechar las clases de utilidad predefinidas, a menudo puedes reducir significativamente el tamaño total de tus archivos CSS, lo que lleva a tiempos de carga de página más rápidos y un mejor rendimiento.Comunidad y Ecosistema Sólidos: Tailwind cuenta con una comunidad grande y activa, proporcionando acceso a documentación extensa, recursos útiles y una gran cantidad de plugins y extensiones construidos por la comunidad.En mi experiencia, la curva de aprendizaje inicial de Tailwind es relativamente menor. La mayoría de los desarrolladores se vuelven competentes en una semana, y los beneficios a largo plazo en términos de velocidad de desarrollo y mantenibilidad superan con creces la inversión inicial.Te animo a probar Tailwind. Podrías sorprenderte de cuánto puede simplificar tu flujo de trabajo de CSS y aumentar tu productividad.Obtención de datos en ReactReact/Tanstack QueryPara la mayoría de las necesidades de obtención de datos, priorizo los Componentes del Servidor debido a sus ventajas inherentes de rendimiento y mejora en la seguridad de los datos. Al manejar la carga de datos en el servidor, puedo minimizar la cantidad de JavaScript ejecutado en el navegador, lo que resulta en cargas iniciales de página más rápidas y una mejor experiencia de usuario.Sin embargo, para escenarios más complejos como el scroll infinito, la paginación o las actualizaciones de datos en tiempo real, aprovecho el poder de React Query. React Query proporciona una solución robusta y flexible para gestionar la obtención de datos, el almacenamiento en caché y las actualizaciones en el lado del cliente.Ejemplo:Componentes del Servidor: Ideal para obtener datos iniciales para una página de producto, perfil de usuario o publicación de blog.React Query: Excelente para implementar scroll infinito en un feed, gestionar datos paginados en una tabla o manejar actualizaciones en tiempo real para una aplicación de chat.Al combinar estratégicamente Componentes del Servidor y React Query, puedo lograr un equilibrio óptimo entre rendimiento, mantenibilidad y experiencia del desarrollador en mis aplicaciones React.Base de Datos & ORMPrismaMi Elección Preferida para Interacciones con la Base de DatosPrisma ORM sigue siendo mi elección preferida para interactuar con bases de datos en mis proyectos React. Aunque ORMs más nuevos como Drizzle están ganando tracción, Prisma ha demostrado ser una solución estable y confiable con una comunidad fuerte y documentación extensa.Características Clave de Prisma:Seguridad de Tipos: Prisma genera tipos de TypeScript a partir de tu esquema de base de datos, asegurando la seguridad de tipos en toda tu aplicación y reduciendo el riesgo de errores en tiempo de ejecución.Ejemplo:const user = await prisma.user.findUnique({ where: { id: 1 }, include: { posts: true }, });Los tipos generados para user y posts proporcionan una guía clara y previenen estructuras de datos inesperadas.Definición Declarativa del Esquema: Define tu esquema de base de datos usando Prisma Schema Language, una sintaxis declarativa e intuitiva.Ejemplo:model User { id Int @id @default(autoincrement()) name String email String @unique posts Post[] } model Post { id Int @id @default(autoincrement()) title String content String author User @relation(fields: [authorId], references: [id]) authorId Int }Consulta Simplificada: Prisma proporciona una API de creación de consultas fluida e intuitiva, lo que facilita la escritura de consultas complejas a la base de datos con un esfuerzo mínimo.Migraciones: Prisma Migrate simplifica los cambios en el esquema de la base de datos con un sistema de migración fácil de usar, permitiéndote evolucionar tu base de datos de manera segura con el tiempo.Beneficios de Usar PrismaAumento de la Productividad: Prisma mejora significativamente la productividad del desarrollador al automatizar tareas repetitivas, como la generación de consultas SQL y la gestión de cambios en el esquema de la base de datos.Mejora de la Calidad del Código: La seguridad de tipos, los tipos generados y el enfoque en las mejores prácticas contribuyen a una mayor calidad del código y a menos errores.Mantenibilidad Mejorada: El enfoque declarativo de Prisma y las definiciones claras del esquema facilitan la comprensión y el mantenimiento de las interacciones con la base de datos a lo largo del tiempo.Comunidad y Ecosistema Sólidos: Prisma cuenta con una comunidad grande y activa, proporcionando acceso a documentación extensa, tutoriales y recursos de soporte.Aunque ORMs más nuevos como Drizzle ofrecen características prometedoras, la estabilidad de Prisma, su ecosistema maduro y su fuerte enfoque en la experiencia del desarrollador lo convierten en mi elección preferida para la mayoría de los proyectos.SupabaseSupabase es una alternativa de código abierto a Firebase que ofrece una suite completa de servicios backend, incluyendo una base de datos PostgreSQL en tiempo real, autenticación, almacenamiento y edge-functions. Proporciona a los desarrolladores una forma rápida y eficiente de construir aplicaciones web full-stack sin la molestia de gestionar la infraestructura.Características Clave de Supabase:PostgreSQL en Tiempo Real: Supabase aprovecha PostgreSQL por sus capacidades robustas de base de datos, permitiéndote crear modelos de datos complejos y realizar consultas poderosas. Las características en tiempo real te permiten construir aplicaciones con actualizaciones en vivo, como aplicaciones de chat y paneles de control.Autenticación: Supabase proporciona un sistema de autenticación flexible que soporta varios métodos como email/contraseña, inicios de sesión sociales y proveedores de autenticación personalizados. También ofrece características como autenticación sin contraseña y autenticación multifactor.Almacenamiento: Supabase incluye un servicio de almacenamiento de archivos que te permite subir y gestionar archivos directamente desde tu aplicación. Puedes generar URLs públicas para los archivos y establecer permisos para controlar el acceso.Funciones en el Borde: Estas funciones serverless te permiten ejecutar código personalizado en el borde, más cerca de tus usuarios. Esto es útil para tareas como transformación de datos, renderizado del lado del servidor y lógica de autenticación personalizada.API GraphQL: Además de la API REST, Supabase también ofrece una API GraphQL, proporcionando una forma más flexible y expresiva de consultar tus datos.¿Por Qué Elegir Supabase?Desarrollo Rápido: Supabase acelera el desarrollo proporcionando servicios backend preconstruidos, permitiéndote enfocarte en construir el frontend de tu aplicación.Escalabilidad: Supabase está construido sobre una infraestructura escalable, haciéndolo adecuado para aplicaciones de todos los tamaños.Código Abierto: Al ser de código abierto, Supabase ofrece transparencia, flexibilidad y una comunidad fuerte.Rentable: Supabase ofrece un generoso nivel gratuito y planes de precios flexibles, haciéndolo asequible para proyectos pequeños y grandes.Cuándo Usar SupabaseAplicaciones en Tiempo Real: Supabase es ideal para aplicaciones que requieren actualizaciones en tiempo real, como aplicaciones de chat, herramientas colaborativas y paneles de control.Prototipado Rápido: La facilidad de uso de Supabase lo convierte en una excelente opción para construir rápidamente prototipos y MVPs.Aplicaciones Web Full-Stack: Supabase puede ser utilizado como el backend para aplicaciones web tanto simples como complejas.Manejo y Validación de DatosTypeScriptTypeScript es innegablemente el estándar de la industria para proyectos JavaScript. Su sistema de tipos estático, combinado con características modernas como interfaces y módulos, ofrece una serie de ventajas, como una mayor seguridad de tipos, una mejor detección de errores, una mayor productividad y una experiencia de desarrollo más agradable. La adopción de TypeScript por parte de la industria es un testimonio de su valor y eficacia.ZodUna poderosa herramienta para la validación Type-SafeZod ha emergido como una opción líder para la validación en proyectos React, particularmente cuando se combina con TypeScript. Al aprovechar el enfoque de tipo seguro de Zod, puede mejorar significativamente la robustez y la capacidad de mantenimiento de sus aplicaciones.Características Clave de ZodValidación Segura por Tipos: Zod aprovecha el sistema de tipos de TypeScript para definir y hacer cumplir esquemas de datos. Esto asegura que los datos recibidos por tu aplicación se ajusten a la estructura esperada, previniendo errores inesperados y mejorando la integridad de los datos.Esquemas Declarativos: Zod te permite definir esquemas de datos de manera declarativa usando una sintaxis concisa y expresiva. Esto facilita la creación de reglas de validación complejas para tus datos.Manejo de Errores: Zod proporciona mensajes de error detallados e informativos, lo que facilita la identificación y corrección de problemas de validación. Estos mensajes de error pueden integrarse fácilmente en tu interfaz de usuario para proporcionar retroalimentación útil a los usuarios.Extensibilidad: Zod ofrece una API flexible y extensible, permitiéndote crear reglas de validación personalizadas e integrarlas con otras partes de tu aplicación.Beneficios de Usar ZodMejora de la Calidad del Código: Al hacer cumplir tipos de datos y reglas de validación, Zod te ayuda a escribir código más robusto y confiable con menos errores inesperados.Mejora de la Experiencia del Desarrollador: El enfoque seguro por tipos de Zod y sus mensajes de error informativos mejoran significativamente la experiencia del desarrollador al facilitar la escritura, depuración y mantenimiento de tu código.Mejora de la Experiencia del Usuario: Al proporcionar mensajes de error claros y útiles a los usuarios, Zod ayuda a mejorar la experiencia general del usuario de tu aplicación.Reducción de Costos de Mantenimiento: Al detectar problemas de validación de datos desde el principio, Zod puede ayudar a reducir los costos de mantenimiento a largo plazo asociados con tu aplicación.Mi EnfoqueAunque Zod ofrece potentes capacidades de validación del lado del cliente, prefiero usarlo principalmente para la validación del lado del servidor, particularmente dentro de las Acciones del Servidor. Este enfoque mantiene los formularios del lado del cliente ligeros y evita la complejidad introducida por muchas bibliotecas de formularios de terceros. Al confiar en la validación nativa de HTML para verificaciones básicas, puedo mantener una arquitectura de componentes de formularios ágil y eficiente.Pruebas y herramientasMock Service Worker (MSW)Una herramienta que ha mejorado drásticamente mi flujo de trabajo es Mock Service Worker (MSW). Si aún no la usas, déjame mostrarte por qué merece tu atención.Mock Service Worker es una potente librería JavaScript para API mocking. Intercepta peticiones a nivel de red usando Service Workers, permitiéndote simular APIs directamente en el navegador o en tiempo de ejecución Node.js. Esto lo hace perfecto para pruebas, depuración e incluso desarrollo sin depender de un backend.Por qué me encanta usar MSWPara mí, MSW resuelve muchos problemas que otras librerías de mocking no pueden:Mocking Realista: MSW intercepta solicitudes a nivel de red, por lo que el comportamiento simulado es casi indistinguible de un servidor real. Es como tener un emulador de backend en tu bolsillo.Pruebas de Cliente y Servidor: Ya sea que estés probando una aplicación React o un servicio Node.js, MSW funciona perfectamente en ambos entornos.Reducción de Dependencias: No necesitas servidores de prueba adicionales ni configuraciones de mocking complejas. MSW lo mantiene limpio y simple.Flexibilidad: Puedes simular APIs REST, GraphQL e incluso WebSocket. Si tu aplicación puede hacer la solicitud, MSW puede simularla.Mejor Depuración: Con registros claros y herramientas de depuración, sabes exactamente qué solicitudes están siendo simuladas y cómo.MSW vs. Herramientas Mocking TradicionalesEn mi experiencia, MSW destaca sobre herramientas como los interceptores Axios o los mocks personalizados:Escalabilidad: Con MSW, tus mocks viven fuera de la lógica de tu aplicación, haciéndolos reutilizables y mantenibles.Aislamiento: A diferencia de los interceptores, MSW no interfiere con el código de tu aplicación. Esto significa que no hay código desordenado de desmontaje después de las pruebas.Comportamiento Similar al Navegador: Al usar Service Workers, MSW imita el comportamiento a nivel del navegador, asegurando que tus pruebas sean lo más cercanas posible a las condiciones del mundo real.Por Qué Deberías Probar MSWLas APIs son la columna vertebral de las aplicaciones modernas, y probarlas no tiene por qué ser doloroso. MSW proporciona una forma realista, flexible y amigable para el desarrollador de simular APIs sin complejidad innecesaria.Ya sea que estés desarrollando, depurando o probando, MSW es un cambio de juego. Es la herramienta que no sabía que necesitaba, pero de la que ahora no puedo prescindir.Si estás buscando elevar tu proceso de desarrollo en 2025, prueba MSW. Tu equipo te lo agradecerá y tu código brillará.PlaywrightCuando se trata de pruebas web modernas en 2025, Playwright se ha convertido en una de mis herramientas de referencia. No es sólo una biblioteca de pruebas; se siente como una herramienta de poder para los desarrolladores front-end que quieren precisión, velocidad y versatilidad.Playwright es una biblioteca Node.js para la automatización del navegador. Creada por Microsoft, permite escribir pruebas de extremo a extremo para aplicaciones web en los principales navegadores (Chromium, Firefox, WebKit) con una API coherente. Es como tener una navaja suiza para las pruebas de navegador que es elegante, potente y fácil de usar para los desarrolladores.Por qué destaca PlaywrightDesde mi experiencia, Playwright destaca en:Soporte Multi-Navegador: A diferencia de Cypress, que solo soporta navegadores basados en Chromium de forma predeterminada, Playwright te permite probar en Chromium, Firefox y WebKit. Esto lo hace indispensable para asegurar que tu aplicación funcione en diferentes entornos.Pruebas en Paralelo: La paralelización integrada de Playwright es un cambio de juego. Las pruebas se ejecutan más rápido, lo que mantiene la tubería de CI fluida y a los desarrolladores productivos.Modos Headless y Headed: Ya sea que estés depurando o ejecutando pruebas en CI, Playwright se adapta sin problemas.Aislamiento de Contextos: Con Playwright, puedes crear contextos de navegador aislados que imitan diferentes usuarios. Esto es una salvación para aplicaciones con flujos de autenticación complejos o escenarios multi-tenant.Pruebas de API: Playwright no se detiene en la UI. Puedes hacer llamadas API directamente dentro de tus scripts de prueba, asegurando que tu front-end y back-end funcionen armoniosamente.Veamos algo de códigoHe aquí un ejemplo rápido de cómo escribir una prueba Playwright en TypeScript. Esta prueba comprueba una página de inicio de sesión:import { test, expect } from "@playwright/test"; test.describe("Login Page Tests", () => { test("should log in successfully with valid credentials", async ({ page, }) => { await page.goto("https://example.com/login"); // Fill out the login form await page.fill("#username", "testuser"); await page.fill("#password", "securepassword"); await page.click('button[type="submit"]'); // Assert redirection to the dashboard await expect(page).toHaveURL("https://example.com/dashboard"); await expect(page.locator("h1")).toHaveText("Welcome, testuser!"); }); test("should show an error for invalid credentials", async ({ page }) => { await page.goto("https://example.com/login"); // Fill out the form with invalid data await page.fill("#username", "wronguser"); await page.fill("#password", "wrongpassword"); await page.click('button[type="submit"]'); // Assert error message is displayed await expect(page.locator(".error-message")).toHaveText( "Invalid credentials" ); }); });Las pruebas ya no son opcionales en 2025. Los usuarios esperan experiencias impecables, y la automatización es la forma de ofrecerlas. Playwright combina potencia con funciones fáciles de usar para los desarrolladores, lo que la convierte en una herramienta imprescindible.Si aún no la ha explorado, ahora es el momento. Su yo del futuro se lo agradecerá cuando sus pruebas se ejecuten más rápido, sus errores disminuyan y sus usuarios estén contentos.Despliegue y alojamientoCloudflare (Dominio & CDN)Cloudflare sigue siendo una piedra angular del desarrollo web moderno. Para mí, no es sólo un servicio, es una parte integral de la creación de aplicaciones rápidas, seguras y escalables. Tanto si eres un desarrollador independiente como si formas parte de un gran equipo, Cloudflare tiene herramientas que elevarán tu pila.¿Qué es Cloudflare?Cloudflare es un conjunto completo de herramientas de rendimiento y seguridad web. Comenzó como una red de distribución de contenidos (CDN), pero hoy en día es mucho más. Con Cloudflare, puedes optimizar el rendimiento de tu sitio web, protegerlo de ataques maliciosos e incluso crear aplicaciones sin servidor utilizando su potente plataforma de computación edge.Por qué confío en CloudflareEstas son las razones más destacadas por las que Cloudflare es una parte esencial de mi stack:Velocidad en Todas Partes: Con su CDN global, Cloudflare asegura que los activos estáticos de tu aplicación se entreguen a la velocidad del rayo, sin importar dónde estén tus usuarios. Su caché es una salvación para aplicaciones con activos pesados o audiencias globales.Seguridad Inigualable: El Firewall de Aplicaciones Web (WAF) y la protección contra DDoS de Cloudflare me han ahorrado innumerables dolores de cabeza. Es como tener un equipo de seguridad en piloto automático.Computación Serverless en el Borde: Usar Cloudflare Workers ha sido un cambio de juego. Me permite ejecutar funciones ligeras en el borde, reduciendo la latencia y descargando trabajo de los servidores tradicionales.Facilidad de Uso: Configurar Cloudflare toma minutos, pero los beneficios son inmensos. Su panel intuitivo y herramientas amigables para desarrolladores hacen que sea fácil integrarlo con cualquier stack.Rentable: Por el valor que proporciona, el precio de Cloudflare es inmejorable. Incluso su nivel gratuito está lleno de características que pueden ayudarte a empezar sin preocuparte por los costos.Crear aplicaciones modernas significa ofrecer experiencias rápidas, seguras y fiables. Cloudflare te permite conseguir todo esto sin complicar en exceso tu stack. Desde su imbatible CDN hasta su innovadora plataforma Edge Computing, es una herramienta que recomendaría a cualquier desarrollador que quiera preparar sus aplicaciones para el futuro en 2025.Si aún no ha explorado Cloudflare, ahora es el momento perfecto. Sus usuarios notarán la diferencia, y usted también.Otras Utilidades:React Email & ResendUna potente combinación para la entrega de correo electrónicoReact Email y Resend ofrecen una solución convincente para crear y entregar correos electrónicos de alta calidad dentro de sus aplicaciones React.React Email: Esta biblioteca te permite crear plantillas de correo electrónico visualmente atractivas y responsivas directamente dentro de tus componentes React. Aprovechando conceptos familiares de React como componentes, estado y props, puedes crear diseños de correo electrónico dinámicos y fáciles de mantener.Resend: Esta robusta API de correo electrónico proporciona una forma confiable y eficiente de enviar correos electrónicos transaccionales, como correos de bienvenida, restablecimientos de contraseña y confirmaciones de pedidos. Resend ofrece características como alta entregabilidad, análisis robustos e integración fácil con tu infraestructura existente.Beneficios ClaveMejor Experiencia del Desarrollador: React Email mejora la experiencia del desarrollador al permitirte crear plantillas de correo electrónico utilizando patrones familiares de React, lo que lleva a una mayor productividad y mantenibilidad.Branding Consistente: Al usar componentes React para tus plantillas de correo electrónico, puedes asegurar un branding y estilo consistentes en toda tu aplicación, incluidos los correos electrónicos.Mejor Entregabilidad: La infraestructura robusta de Resend y su enfoque en la entregabilidad ayudan a asegurar que tus correos electrónicos lleguen a los destinatarios previstos de manera confiable.Integración Fácil: Resend ofrece una API sencilla y SDKs para una fácil integración con tu aplicación React.Ejemplo:// src/components/EmailTemplates/WelcomeEmail.jsx import * as React from "react"; import { Html, Head, Title, Body, P, H1 } from "@react-email/components"; export const WelcomeEmail = ({ name }) => ( <Html> <Head> <Title>Welcome to Our App!</Title> </Head> <Body> <H1>Hello, {name}!</H1> <P>Welcome to our app! We're excited to have you join us.</P> {/* ... more email content ... */} </Body> </Html> );// src/pages/api/sendWelcomeEmail.js import { Resend } from "resend"; const resend = new Resend(process.env.RESEND_API_KEY); export default async function handler(req, res) { try { await resend.emails.send({ from: "no-reply@yourdomain.com", to: "recipient@example.com", subject: "Welcome to Our App!", html: await renderToString(<WelcomeEmail name="John Doe" />), }); res.status(200).json({ success: true }); } catch (error) { console.error(error); res.status(500).json({ error: "Failed to send email" }); } }Este ejemplo muestra cómo utilizar React Email para crear una plantilla de correo electrónico de bienvenida sencilla y, a continuación, utilizar la API Resend para enviarla.Al combinar la potencia de React Email y Resend, puede agilizar sus flujos de trabajo de correo electrónico, mejorar la calidad de sus comunicaciones por correo electrónico y mejorar la experiencia general del usuario.StripeStripe es una pasarela de pago robusta y ampliamente utilizada que ofrece un conjunto completo de funciones para aceptar pagos en línea.Retos potencialesComplejidad: Aunque es potente, el amplio conjunto de características de Stripe puede resultar abrumador, especialmente para proyectos más pequeños o aquellos con requisitos de pago más simples.API en Evolución: Stripe introduce continuamente nuevas características y actualiza su API, lo que ocasionalmente puede requerir ajustes en tu integración.import React, { useState } from "react"; import { loadStripe } from "@stripe/stripe-js"; const stripePromise = loadStripe("YOUR_STRIPE_PUBLIC_KEY"); function CheckoutForm() { const [loading, setLoading] = useState(false); const handleSubmit = async (event) => { event.preventDefault(); setLoading(true); try { const stripe = await stripePromise; const { error } = await stripe.redirectToCheckout({ lineItems: [ { price: "price_1234567890abc123", quantity: 1, }, ], }); if (error) { console.error(error); // Handle error (e.g., display an error message to the user) } } catch (error) { console.error(error); } finally { setLoading(false); } }; return ( <form onSubmit={handleSubmit}> {/* ... form fields ... */} <button type="submit" disabled={loading}> {loading ? "Processing..." : "Pay Now"} </button> </form> ); } export default CheckoutForm;Esencialmente, esta es la pila tecnológica que yo elegiría hoy para un nuevo proyecto React full-stack. Esta es solo una combinación posible, y la mejor pila tecnológica para tu proyecto dependerá en última instancia de tus requisitos y prioridades específicos. Te animo a explorar estas tecnologías y experimentar con diferentes combinaciones para encontrar lo que mejor funciona para ti.¡Espero que esto haya sido útil y/o te haya enseñado algo nuevo!Profile@khriztianmoreno �

Patrones de obtención de datos en React

2024-12-09
reactjavascriptweb-development

Imagina construir una página web que muestre datos meteorológicos en tiempo real o una lista de productos de una tienda en línea. ¿Cómo obtiene esta información tu aplicación React? La respuesta está en la obtención de datos. Este proceso implica recuperar datos de varias fuentes (como APIs, bases de datos) e incorporarlos en tus componentes de React.Obtención de Datos Secuencial:Piensa en la obtención de datos secuencial como un proceso paso a paso. Obtienes una pieza de datos, esperas a que llegue y luego pasas a la siguiente.Ejemplo: Obtener información del usuario, luego sus pedidos y finalmente su dirección.// Sequential fetching using async/await async function fetchData() { const user = await fetchUser(); const orders = await fetchOrders(user.id); const address = await fetchAddress(user.id); // ... }Obtención de Datos en Paralelo:En la obtención de datos en paralelo, se realizan múltiples solicitudes de datos simultáneamente.Ejemplo: Obtener información del usuario, pedidos y dirección al mismo tiempo.// Parallel fetching using Promise.all Promise.all([fetchUser(), fetchOrders(userId), fetchAddress(userId)]) .then(([user, orders, address]) => { // ... }) .catch((error) => { // ... });Prefetching de Datos:Para mejorar la velocidad percibida de tu aplicación, considera prefetching de datos antes de que sean necesarios. Esta técnica es particularmente efectiva para datos que probablemente se necesitarán pronto pero no de inmediato. Por ejemplo, al utilizar un framework como Next.js construido sobre React, puedes hacer prefetch la página siguiente y sus datos asociados usando su componente Link.Ejemplo:<Link href="/posts/1" prefetch> <a>Post 1</a> </Link>Tan pronto como este componente Link se vuelve visible en la pantalla, los datos para la "Página Siguiente" se precargan. Estas optimizaciones sutiles pueden mejorar significativamente el rendimiento percibido de tu aplicación, haciéndola sentir más receptiva.Conclusión:Elegir el patrón de obtención de datos adecuado depende de tu caso de uso específico.Secuencial: Simple de implementar, adecuado para aplicaciones de pequeña escala.Paralelo: Mejora el rendimiento para conjuntos de datos más grandes, pero puede ser más complejo.Prefetching: Mejora la experiencia del usuario al reducir los tiempos de carga percibidos.Puntos Clave:Async/await: Una forma moderna de manejar operaciones asíncronas en JavaScript.Promesas: Una forma de representar la eventual finalización (o falla) de una operación asíncrona.Rendimiento: La obtención de datos en paralelo y el prefetching pueden mejorar significativamente el rendimiento.Experiencia del usuario: El prefetching puede hacer que tu aplicación se sienta más rápida.Consejos Adicionales:Manejo de errores: Siempre maneja los errores de manera elegante para proporcionar una mejor experiencia de usuario.Caché: Almacena datos accedidos frecuentemente para reducir el número de solicitudes de red.Gestión de estado: Usa bibliotecas como Redux o Zustand para gestionar el estado complejo de la aplicación, especialmente cuando se trata de datos obtenidos.Al entender estos patrones, puedes construir aplicaciones React más eficientes y receptivas.¿Te gustaría que elaborara alguno de estos conceptos o proporcionara más ejemplos de código?Profile@khriztianmoren

Por qué es tan difícil pasar el estado entre los componentes del cliente y del servidor

2024-03-28
javascriptreactweb-development

La forma en que representamos los componentes del servidor es diferente.Nada parecido a lo que estamos acostumbrados hasta ahora.Y debido a que es tan diferente, también cambia dónde manejamos el estado, cómo lo manejamos y cómo logramos dormir por la noche sabiendo que todas estas son cosas importantes que deberíamos saber desde el año pasado, pero la mayoría de nosotros somos completamente inconscientes.WHY?De hecho, los componentes del servidor impactan 3 de las partes más importantes del desarrollo web:PerformanceExperiencia del usuarioLa forma en que nosotros, los desarrolladores, escribimos código y diseñamos nuestras aplicaciones.No es algo que podamos ignorar o tomar a la ligera.Como puedes ver, he estado pensando mucho en ello y probablemente tú también lo hayas estado pensando. Todo desarrollador que valore su teclado está pensando en ello.Y está esta pregunta específica... Es como una pregunta del tipo “la gallina y el huevo”, principalmente porque ambas son preguntas que se hacen mucho.¿Cómo diablos manejo el estado en los componentes del servidor si no tengo acceso al estado en primer lugar?Antes de darte la respuesta, déjame explicarte el problema que nos ocupa. Considere lo que sucede cuando un componente del servidor solicita una nueva renderización.A diferencia de los componentes del cliente donde el estado se conserva entre renderizaciones, los componentes del servidor no pueden darse ese lujo. Como un juego pícaro, siempre empiezan desde cero.No existe ningún código o mecanismo inherente que pueda hacer que un componente del servidor recuerde el estado. El backend tiene todas esas bases de datos y patrones de diseño y todas esas funciones complejas y ¿para qué? Ni siquiera puede manejar el estado.¿Asi que que hacemos? ¿Utilizamos simplemente componentes de servidor en componentes completamente estáticos que no necesitan ningún estado? Si bien esta es una posible respuesta, también es un enfoque que limita la efectividad y el ajuste de los componentes del servidor en las aplicaciones web modernas. Entonces, lo estamos descartando.Porque todo lo que dije anteriormente tiene un inconveniente.Si bien es posible que el backend no maneje el estado del cliente como lo hace el cliente, sí maneja el estado de la aplicación. Entonces, en cierto modo, podemos manejar el estado en el servidor. Simplemente no de la forma en que lo piensas. Y, en realidad, no es una única manera.Y, en realidad, no es una única manera.Hay TRES formas de manejar el estado en el servidor.Cuál elegimos depende de lo que mejor se adapte a nuestras necesidades y situación actual. Y estas 3 formas son:Prop drilling desde el servidor a los componentescookiesstate hydrationAhora, otra pregunta del millón. ¿Por qué no podemos simplemente manejar todos los estados en el cliente?Esto se debe a que los componentes del servidor abogan por una separación de preocupaciones. Lo que en términos más simples significa que cada parte de la aplicación debe ocuparse de sus propios asuntos. Al desacoplar el estado del renderizado, no solo mejoramos el rendimiento, sino que también obtenemos más control sobre la experiencia del usuario.Profile@khriztianmoren

¿Seguirás utilizando componentes del lado del cliente en 2024?

2024-02-14
javascriptreactweb-development

Me encantan los componentes del servidor. Pero no son para todas las ocasiones. De hecho, usarlos en todas y cada una de las oportunidades que tengas es más como ablandar un bistec con el mismo martillo que usaste para clavar un alfiler.Dicho esto, también hay algunos casos en los que los componentes del servidor encajan como Cenicienta y su zapato.Dashboards & ReportsEn el caso de los paneles y los informes, se maximiza el rendimiento al procesar y representar todos los datos en el servidor y, al mismo tiempo, permitir que el cliente haga lo que se suponía que debía hacer en primer lugar.Si solo usamos componentes del cliente, le estamos descargando más tareas y haciendo que desempeñe más tareas de las que potencialmente puede manejar.Si procesó y representó los datos en el cliente, pasaría mucho tiempo esperando con un feo spinner burlándose de usted debido a todos los pasos adicionales que el cliente tiene que seguir para lograr el mismo resultado.Primero, necesitaría obtener los datos de su endpoint, que a su vez tendría que obtener datos de la base de datos, que a su vez tendría que obtener datos de sus registros.No sólo eso, sino que también hay que esperar pacientemente a que los datos lleguen al cliente, aunque llegue tarde.Y sólo una vez que llegan, el cliente puede comenzar a procesarlos y mostrárselos al usuario.Por eso, en este caso, es mejor tener los componentes bloqueados y renderizados directamente en el servidor.Y luego, el cliente puede obtener todos los widgets que su corazón electrónico desea, todos transmitidos en paralelo, lo que es una forma mucho más rápida y sencilla de realizar negocios.Blog PostsLas publicaciones de blog son algunos de los contenidos más estáticos que puedes encontrar. Después de todo, se trata principalmente de un montón de palabras, en orden, con alguna imagen, gif o meme ocasional aquí y allá.Con los componentes del servidor, estás renderizando previamente el contenido en el servidor, que es el mejor de los casos en términos de SEO porque se entrega rápido y completo.Este caso de uso anterior es lo que tiende a desequilibrar a los desarrolladores y confundirlos. Porque las publicaciones de blogs son lo primero en lo que también piensan cuando se trata de SSR. Entonces, si piensan en SSR y componentes de servidor cuando piensan en publicaciones de blog, es natural pensar que ambos son lo mismo o que pueden usarse indistintamente.Lo cual es total y absolutamente incorrecto y es un pecado digno de arder en el infierno por la eternidad, según mi blog post anterior.Pero al mismo tiempo tiene sentido desde el punto de vista de los resultados. Porque aunque sus enfoques son muy diferentes en la práctica, los resultados son bastante similares.Server-Side Data FetchingLa obtención de datos del lado del servidor es una excelente manera de darle a su código un impulso de seguridad en caso de que, de lo contrario, revele lógica o claves API que se supone deben permanecer ocultas o si está paranoico con respecto a cada pieza de información que posee.Puede utilizar este tipo de obtención de datos para acceder no sólo a su base de datos sino también a cualquier otra API que desee. Todo ello siendo astuto.Sin embargo, hay casos en los que los componentes del servidor NO son ideales y, de hecho, deben evitarse.Requisitos de alta interactividadEsta es una redacción elegante para cualquier cosa a la que le haces algo y le devuelves algo. Algo así como gelatina, pero no tanto.Algo potencialmente más familiar y más acorde con el desarrollo web en sí son elementos como formularios y botones.Estos componentes a menudo tienen que reaccionar de alguna manera a sus acciones, pueden tener su propio estado y comunicarse con otros componentes en el lado del cliente, lo que los convierte en el eslabón más débil cuando se trata de componentes de servidor.Stateful ComponentsSi lo tomas lo más literalmente posible y usas la definición que hemos estado usando hasta ahora, no hay manera de manejar el estado en un componente del servidor.Pero si entrecierras los ojos, inclinas la cabeza un poco hacia un lado, desenfocas un poco y respiras profundamente, podrás ver que esto es sólo una verdad a medias.En otro momento aprenderemos cuáles son los matices, pero por ahora digamos que los componentes del servidor NO tienen acceso al estado. Después de todo, no tienen acceso a hooks relacionados con el estado.ConclusiónLos componentes del servidor son una herramienta poderosa para escenarios específicos en el desarrollo web. Utilícelos para mejorar el rendimiento y la seguridad de tareas con uso intensivo de datos. Pero recuerde, es posible que no se adapten a todas las situaciones, especialmente para elementos interactivos o con estado.Profile@khriztianmoreno Hasta la próxima

Server Components Vs Server-side Rendering

2024-01-28
javascriptreactweb-development

¿Sabías que los componentes del servidor y el renderizado del lado del servidor son dos cosas completamente diferentes?Image descriptionY si bien van de la mano en muchos casos, hay igualmente muchos ejemplos en los que puedes y debes usar solo uno de ellos.Image descriptionAhora bien, para ser justos, dada la documentación en línea que la mayoría de los desarrolladores encuentran sobre los componentes del servidor y el renderizado del lado del servidor, el hecho de que asuman que estas dos cosas son iguales no es exactamente una sorpresa.(Esto también les da la excusa perfecta para evitar los componentes del servidor por completo, en lugar de enfrentar el hecho de que esto es algo que ya deberían saber usar bastante bien y que eventualmente tendrán que aprender de todos modos)Image descriptionDicho esto, los componentes del servidor tienen muchas ventajas sobre el renderizado del lado del servidor, especialmente cuando se trata de crear aplicaciones más grandes y complejas.Hablemos un poco más de las diferencias entre ambos.Server-Side RenderingLa representación del lado del servidor representa la página en el servidor. Pero, obviamente, eso no es realmente útil, así que profundicemos un poco más.La representación del lado del servidor representa la página en el servidor en el momento de la solicitud, lo que significa que cada vez que un cliente realiza una solicitud al servidor, como cuando un nuevo visitante llega a su página, el servidor vuelve a representar la misma página y la envía a el cliente.Y si bien esto es excelente para SEO, ya que incluso las páginas más dinámicas aparecen como estáticas a los ojos de los robots que las indexan y las usan para búsquedas, la representación del lado del servidor tiene muchos pasos entre el cliente que realiza la solicitud al servidor y La página finalmente se carga frente a ti.Primero, cuando la solicitud llega al servidor, el servidor representa estáticamente la página y la envía de regreso al cliente, donde el usuario obtiene una versión de su página que está desprovista de toda interactividad.Pero eso no es lo único que el servidor envía al cliente. Junto con el HTML de la página estática, el servidor envía sus condolencias junto con un gran paquete de código React que el cliente deberá ejecutar para que la página vuelva a ser dinámica.Pero ¿qué pasa cuando el 90% de nuestra página es estática?Podrías pensar que la respuesta correcta es “prácticamente nada” y no estarías exactamente equivocado, pero al igual que en la clase de Cálculo, pierdes puntos porque esta no es la respuesta que estaba buscando.En realidad, todavía se envía una gran cantidad de JavaScript al cliente y debe ejecutarse sin cambiar mucho en la página misma.Esto es una pérdida de tiempo y datos y es una de las principales razones por las que se crearon los componentes del servidor.(Lo que también significa que si está utilizando SSR como alternativa a los componentes del servidor, ha tenido un gran problema y es hora de cambiar su forma de actuar antes de que lo arrojen a una cárcel de "rendimiento lento").Server ComponentsLos componentes del servidor, como SSR, se representan en el servidor, pero tienen la capacidad única de incluir lógica del lado del servidor sin enviar ningún JavaScript adicional al cliente, ya que los componentes del servidor se ejecutan en el servidor.Esto significa que mientras en SSR el código JavaScript se ejecuta en el cliente, en Server Components, el código se ejecuta directamente en el servidor. Y el cliente solo recibe la salida del código a través de la carga útil del servidor, como un bebé al que le mastican la comida.Entonces, en pocas palabras, la diferencia entre componentes de servidor y renderizado del lado del servidor tiene que ver con cuándo y cómo se ejecuta el código. En el caso de los componentes del servidor, no es necesario enviar ni manejar código adicional en el lado del cliente porque ya lo ejecutamos en el servidor.El único código necesario es si está uniendo los componentes del servidor y del cliente y el cliente tiene que unir los dos.El gran beneficio de los componentes de servidor es que ofrecen un mayor rendimiento porque necesitan menos JavaScript del lado del cliente y descargan todo el procesamiento y la recuperación de datos al servidor mientras el cliente puede relajarse y beber Aperol Spritz hasta que llegue el HTML renderizado.En ese momento, el cliente simplemente se lo muestra al usuario final y se lleva todo el crédito por el arduo trabajo realizado por el servidor.Y si bien esto puede parecer un poco complejo en este momento, todo se aclarará a medida que aprenda más sobre los componentes del servidor. Lo cual es algo que realmente no se puede evitar, ya que se están volviendo cada vez más populares en casos de uso como:Tener muchos cálculos pesados ​​que necesitan mucho procesamientoAcceso API privado (para mantener el secreto… secret)Cuando la mayor parte del lado del cliente ya es estático y sería un desperdicio enviar más JavaScript al clienteConclusiónSi bien los componentes de servidor pueden parecer desalentadores en este momento, en su mayoría son algo nuevo y extraño. Una vez que los conozcas mejor y aprendas algunos de los conceptos básicos, te darás cuenta de que no son tan complejos como parecen.La curva de aprendizaje no es tan pronunciada como podría pensar y solo porque tengan "sever" en el nombre, no significa que tengan que ser algo extraño y críptico de lo que los desarrolladores frontend debamos mantenernos alejados. De hecho, son bastante similares a los componentes del cliente e incluso más livianos ya que carecen de elementos como enlaces de estado, etc.Profile@khriztianmoren

Hacks for effective Fullstack development with React and Node

2023-04-17
javascriptnodejsreact

Hoy te mostraré un flujo de trabajo óptimo para un desarrollo efectivo con Node.js y React. Si alguna vez ha trabajado en un proyecto con varios archivos package.json, es posible que conozca el dolor de hacer malabarismos con varias pestañas de terminal, recordar qué comandos inician qué servidor o manejar los errores de CORS.Afortunadamente, hay algunas herramientas disponibles que pueden aliviar algunos de estos dolores de cabeza.FullstackConfiguración de Monorepo para React y NodeDigamos que estamos trabajando en un monorepo con dos archivos package.json: uno está en un directorio client para un front-end de React impulsado por Create React App, y uno está en la raíz del repositorio para un back-end de Node que expone un API que utiliza nuestra aplicación React. Nuestra aplicación React se ejecuta en localhost:3000 y nuestra aplicación Node se ejecuta en localhost:8080. Ambas aplicaciones se inician con npm startDado que tenemos dos archivos package.json, esto significa que para que nuestro front-end y back-end estén en funcionamiento, debemos asegurarnos de haber ejecutado npm install y npm start tanto en el directorio raíz como en el directorio del cliente. Así es como simplificamos esto.1. Ejecutar dos servidores al mismo tiempoUna mejora que podemos hacer en nuestro flujo de trabajo de desarrollo es agregar una herramienta de compilación para ejecutar varios comandos npm al mismo tiempo para ahorrarnos la molestia de ejecutar npm start en varias pestañas de terminal. Para hacer esto, podemos agregar un paquete npm llamado concurrently a la raíz de nuestro proyecto.En la raíz de nuestro proyecto, lo instalaremos como una dependencia de desarrollo.npm install -D concurrentlyLuego, en nuestras secuencias de comandos root package.json, actualizaremos nuestra secuencia de comandos start para usarlas simultáneamente.{ "name": "my-app", "version": "1.0.0", "main": "index.js", "scripts": { "start": "concurrently --kill-others-on-fail npm run server npm run client", "server": "node index.js", "client": "cd client && npm start" }, "dependencies": { "express": "^4.17.1" }, "devDependencies": { "concurrently": "^6.0.1" } }Ahora, tenemos tres scripts npm:npm run server inicia nuestra aplicación Node,npm run client ejecuta npm start en el directorio del client para iniciar nuestra aplicación React,npm start ejecuta npm run server y npm run client al mismo tiempo.2. Instalar las dependencias de front-end y back-end con un solo comandoOtro aspecto de nuestro flujo de trabajo que podemos mejorar es la instalación de dependencias. Actualmente, necesitamos ejecutar manualmente npm install para cada archivo package.json que tenemos al configurar el proyecto. En lugar de pasar por esa molestia, podemos agregar un postinstall script a nuestro package.json raiz para ejecutar automáticamente npm install en el directorio del client después de que la instalación haya finalizado en el directorio raíz.{ "name": "my-app", "scripts": { ..., "postinstall": "cd client && npm install" }, }Ahora, cuando instalamos nuestro monorepo, todo lo que tenemos que hacer para ponerlo en marcha es ejecutar npm install y luego npm start en la raíz del proyecto. No es necesario ingresar a ningún otro directorio para ejecutar otros comandos.3. Solicitudes API proxy desde el back-endComo mencione anteriormente, nuestro back-end de Node expone los endpoints del API que utilizara nuestra aplicación React. Digamos que nuestra aplicación Node tiene un endpoint /refresh_token.Fuera de la caja, si intentáramos enviar una solicitud GET a http://localhost:8080/refresh_token desde nuestra aplicación React en http://localhost:3000, nos encontraríamos con problemas de CORS. CORS significa intercambio de recursos de origen cruzado.Por lo general, cuando encuentra errores de CORS, es porque está tratando de acceder a los recursos de otro dominio (es decir, http://localhost:3000 y http://localhost:8080), y el dominio del que está solicitando recursos no está permitido.Para decirle al servidor de desarrollo que envíe por proxy cualquier solicitud desconocida a nuestro servidor API en desarrollo, podemos configurar un proxy en el archivo package.json de nuestra aplicación React. En client/package.json, agregaremos un proxy para http://localhost:8080 (donde se ejecuta nuestra aplicación Node).{ "name": "client-app", "proxy": "http://localhost:8080", "dependencies": { "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, ... }Ahora, si reiniciamos el servidor y configuramos una solicitud al endPoint /refresh_token de nuestra aplicación Node (sin http://localhost:8080) usando fetch(), el error CORS debería resolverse.fetch("/refresh_token") .then((res) => res.json()) .then((data) => console.log(data)) .catch((err) => console.error(err));La próxima vez que trabaje en un proyecto monorepo como este, pruebe estos tres consejos para optimizar su flujo de trabajo de desarrollo.¡Eso es todo amigxs! ¡Espero que esto te ayude a convertirte en un o una mejor dev!Profile@khriztianmorenoHasta la próxima

React useEffect

2022-09-05
javascriptreacthooks

useEffect es probablemente el hook más confuso e incomprendido en React. Hoy quiero aclararte eso.Usamos hooks todo el tiempo en Make It Real y comprender useEffect es crucial si vamos a escribir código React de estilo moderno.A continuación veremos:¿Qué es useEffect?Cómo ejecutar un effect(efecto) en cada renderCómo ejecutar un efecto solo en el primer renderCómo ejecutar un efecto en el primer render y volver a ejecutarlo cuando cambia una "dependencia”Cómo ejecutar un efecto con limpieza¿Qué es useEffect?El hook useEffect nos permite realizar side effects(efectos secundarios) en nuestros componentes de función. Los side effects son esencialmente cualquier cosa en la que queremos que suceda una acción "imperativa". Esto es cosas como:Llamadas a APIActualizar el DOMsuscribirse a event listeners(oyentes de eventos)Todos estos son efectos secundarios que podríamos necesitar que un componente haga en diferentes momentos.Ejecutar useEffect en cada renderEl hook useEffect no devuelve ningún valor, sino que toma dos argumentos. Siendo el primero obligatorio y el segundo opcional. El primer argumento es la función callback del efecto que queremos que ejecute Hook (es decir, el efecto en sí). Supongamos que queríamos colocar un mensaje console.log() dentro del callback del useEffect.import { useEffect } from "react"; export const FunctionComponent = () => { useEffect(() => { console.log("run for every componentrender"); }); return ( // ... ); }De forma predeterminada, el efecto establecido en el hook useEffect se ejecuta cuando el componente se renderiza por primera vez y después de cada actualización. Si ejecutamos el código anterior, notaremos que se genera el mensaje console.log('run for every componentrender') a medida que se renderiza nuestro componente. Si nuestro componente alguna vez se volviera a renderizar (por ejemplo, de un cambio de estado con algo como useState), el efecto se ejecutaría nuevamente.A veces, volver a ejecutar un efecto en cada renderizado es exactamente lo que quieres. Pero la mayoría de las veces, solo desea ejecutar el efecto en ciertas situaciones, como en el primer renderizado.Cómo ejecutar el useEffect solo en el primer renderEl segundo argumento del hook useEffect es opcional y es una lista de dependencias que nos permite decirle a React que omita la aplicación del efecto solo hasta que se den ciertas condiciones. En otras palabras, el segundo argumento del hook useEffect nos permite limitar cuándo se ejecutará el efecto. Si simplemente colocamos un array vacío como segundo argumento, así es como le decimos a React que solo ejecute el efecto en el renderizado inicial.import { useEffect } from "react"; export const FunctionComponent = () => { useEffect(() => { console.log("run only for first component render (i.e.component mount)"); }, []); return ( // ... ); }Con el código anterior, el mensaje console.log() solo se activará cuando el componente se monte por primera vez y no se volverá a generar, incluso si el componente se vuelve a renderizar varias veces.Esto es mucho más "eficiente" que ejecutar en cada renderizado, pero ¿no hay un término medio feliz? ¿Qué pasa si queremos rehacer el efecto, si algo cambia?Ejecutar el useEffect en el primer render y volver a ejecutarlo cuando cambie la dependenciaEn lugar de hacer que un efecto se ejecute una vez al principio y en cada actualización, podemos intentar restringir el efecto para que se ejecute solo al principio y cuando cambie cierta dependencia.Supongamos que queríamos lanzar un mensaje console.log() cada vez que cambiara el valor de una propiedad de estado. Podemos lograr esto colocando la propiedad de estado como una dependencia del callback del efecto. Mira el siguiente ejemplo de código:import { useState, useEffect } from "react"; export const FunctionComponent = () => { const [count, setCount] = useState(0); useEffect(() => { console.log( "run for first component render and re-run when 'count' changes" ); }, [count]); return ( <button onClick={() => setCount(count + 1)}> Click to increment count and trigger effect </button> ); };Arriba, tenemos un botón en el template del componente responsable de cambiar el valor de la propiedad de estado de count cuando se hace click. Cada vez que se cambie la propiedad de estado count (es decir, cada vez que se haga click en el botón), notaremos que se ejecuta el callback del efecto y se activa el mensaje console.log().Ejecutar efecto con limpiezaSe ejecuta un callbak de efecto cada vez en el procesamiento inicial y cuando especificamos cuándo se debe ejecutar un efecto. El hook useEffect también brinda la capacidad de ejecutar una limpieza después del efecto. Esto se puede hacer especificando una función de retorne al final de nuestro efecto.import { useState, useEffect } from "react"; export const FunctionComponent = () => { const [count, setCount] = useState(0); useEffect(() => { console.log( "run for first component render and re-run when 'count' changes" ); return () => { console.log("run before the next effectand when component unmounts"); }; }, [count]); return ( <button onClick={() => setCount(count + 1)}> Click to increment count and trigger effect </button> ); };En el ejemplo anterior, notaremos que el mensaje de la función de limpieza se activa antes de que se ejecute el efecto deseado. Además, si nuestro componente alguna vez se desmonta, la función de limpieza también se ejecutará.Un buen ejemplo de cuándo podríamos necesitar una limpieza es cuando configuramos una suscripción a nuestro efecto, pero queremos eliminar la suscripción cada vez que se realice la próxima llamada de suscripción, para evitar memory leaks.A good example of when we might need a cleanup is when we set up a subscription in our effect but want to remove the subscription whenever the next subscription call is to be made, to avoid memory leaks.Estas son principalmente todas las diferentes formas en que el hook useEffect se puede utilizar para ejecutar efectos secundarios en componentes. Te invito a ver esta guia visual de useEffect de ALEX SIDORENKO que ilustra estos conceptos a través de una serie de GIF es a la vez inteligente y eficaz, especialmente para los estudiantes visuales. También hay una visualización de cómo funcionan las funciones de primera clase si quieres más.¡Espero que esto haya sido útil y/o te haya hecho aprender algo nuevo!Profile@khriztianmoreno �

Por qué Storybook? la herramienta de desarrollo de componentes utilizada por más de 30,000 proyectos

2022-08-22
javascriptstorybookreact

Storybook es una herramienta para desarrollar componentes e interfaces de usuario más rápido que nunca. Storybook es increíblemente versátil: puedes usarlo con una variedad de librerías y frameworks de JavaScript, no solo React. Está disponible para Vue, React, Svelte, Angular y Ember.js.StorybookSi has estado desarrollando tus componentes a la antigua usanza, en tu editor de texto o IDE, una herramienta como Storybook te permite desbloquear una mayor productividad al desarrollar componentes. A continuación, aprenderád qué es Storybook, cómo funciona y si es adecuado para tu equipo.Los problemas de desarrollar componentes de forma tradicionalComencemos observando la fricción involucrada con el proceso típico de desarrollo de componentes:Recibes una tarea para desarrollar una función: digamos que es un formulario en la página de pago.Luego, debes configurar el entorno de desarrollo: conectarse a la VPN, ejecutar el backend, ejecutar el frontend, etc.Finalmente, llega a la página en la que vivirá el feature (característica).Es engorroso navegar entre varias páginas, completar formularios y hacer clic en botones cada vez que tiene que llegar a donde debería estar la función. A veces, sus componentes tienen varios estados, por ejemplo, loading, success, y error. No siempre es fácil replicar todos los estados de un componente, lo que lo lleva a modificar el código del componente solo para forzar un estado específico.Storybook aísla tus componentes: depuración de componentes más fácilEs posible que haya pasado por estas situaciones y se haya encontrado con el dolor que implica este tipo de flujo de trabajo de desarrollo de componentes.La mayor parte del tiempo, mientras desarrollas, deseas concentrarte en el componente que estás creando, por lo que otros elementos en una página se vuelven ruido. Tener una forma de acceder rápidamente a cualquier componente o función, y también poder simular todos los casos de uso, es increíblemente beneficioso y te ahorra mucho tiempo.Storybook te brinda este tipo de aislamiento de componentes para que puedas trabajar solo en el componente que tienes en mente, sin tener que interactuar con otros componentes.¿Qué es Storybook?Storybook es una herramienta de código abierto que te ayuda a desarrollar componentes de interfaz de usuario de forma aislada. Se ejecuta en tu base de código, pero por separado de tu aplicación, por lo que funciona como una caja de arena, lo que permite a los desarrolladores no distraerse con API incompletas, datos inestables y otras dependencias externas. Se integra con marcos como React, Vue, Svelte, Angular y otros.Piense en Storybook como un libro real, con un índice de páginas que se vincula a los componentes de la interfaz de usuario. Cada componente tiene historias (stories) que contar sobre sí mismo, y estas historias representan los diferentes estados de la interfaz de usuario de ese componente. Independientemente de la situación, incluso si está desconectado, podrás acceder a esa página y encontrar y jugar fácilmente con los componentes.Debido a sus ventajas de productividad y colaboración, Storybook es utilizado por más de 30_000 proyectos de código abierto, especialmente bibliotecas de componentes. Sin embargo, muchas empresas de tecnología, como Airbnb, Atlassian y JetBrains, se encuentran entre sus usuarios.¿Para quién es Storybook?Algunas personas parecen pensar que Storybook es una herramienta solo para desarrolladores de bibliotecas de componentes y eso ciertamente no lo es.Storybook nos ayuda a construir desde el componente más simple y atómico, como un botón o un input, hasta características complejas o páginas completas.Dado que Storybook nos ayuda a resumir la interfaz de usuario de las aplicaciones, los diseñadores y los QA pueden beneficiarse de ello. Con Storybook, puedes facilitar el desarrollo de un sistema de diseño y compartir un solo lenguaje con los diseñadores. Los QA pueden obtener una descripción general y probar las funcionalidades de forma aislada. Storybook incluso se puede usar para demostrar la funcionalidad a las partes interesadas, como si fuera un demo.Muchas empresas han hecho públicos sus Storybooks. No son solo inspiración, sino una guía de aprendizaje para equipos nuevos en Storybook y puedes encontrar una lista de Storybooks públicos aquí.Como funcionaDesde un aspecto técnico, Storybook es esencialmente una aplicación React que se ejecuta en tu base de código, por separado de tu aplicación principal. Lo inicia ejecutando un comando CLI. Buscará archivos en tu base de código que contengan una extensión .stories.*, reunirá todos esos componentes y los mostrará en una interfaz de usuario agradable.Supongamos que estás creando, por ejemplo, una tarjeta de restaurante. Tendría un archivo RestaurantCard.stories.tsx, que representa el componente con propiedades simuladas para cada escenario.Es importante tener en cuenta que Storybook no produce ningún código de producción. Tus archivos .stories.tsx se utilizan únicamente con fines de desarrollo.¡Espero que esto haya sido útil y/o te haya hecho aprender algo nuevo!Profile@khriztianmoren

Redux explicado de manera simple y sucinta para los desarrolladores de React

2022-08-10
reactreduxjavascript

Redux es una biblioteca de administración de estado ampliamente utilizada para aplicaciones React y TypeScript. Es más fácil que nunca administrar el estado en React gracias al useState React Hook, así como a la API de contexto. Sin embargo, cuando su base de código crezca mucho, necesitará una solución de administración de estado más potente y estructurada, en lugar de ad-hoc. Ahí es donde Redux puede ayudar.Redux¿Por qué necesitas Redux?Cuando trabajas con React, generalmente terminas con un estado que se usa globalmente en toda la aplicación.Uno de los enfoques para compartir el estado en todo el árbol de componentes es usar la API de contexto. A menudo, lo usamos en combinación con hooks como useReducer y useState para administrar el estado global de la aplicación.Este enfoque funciona, pero solo puede llevarte hasta cierto punto. Al final, debes inventar tus propias formas de administrar los side-effects, depurar y dividir código de administración de estado en módulos para que no se convierta en un desastre incomprensible.Una mejor idea es utilizar herramientas especializadas. Una de esas herramientas para administrar el estado de la aplicación global es Redux.Cómo funciona ReduxRedux es un marco de gestión de estado que se basa en la idea de representar el estado global de la aplicación como una función reductora.En Redux, para administrar el estado, definimos una función que acepta dos argumentos: state, para el estado anterior, y action, el objeto que describe la actualización del estado.function reducer(state = "", action: Action) { switch (action.type) { case "SET_VALUE": return action.payload; default: return state; } }Este reductor representa un valor de tipo cadena. Maneja solo un tipo de acción: SET_VALUE.Si el tipo de campo de acción recibido no es SET_VALUE, el reductor devuelve el estado sin cambios.Después de tener el reductor, creamos la store(tienda) usando el método redux createStore.const store = createStore(reducer, "Initial Value");La store proporciona un método de suscripción que nos permite suscribirnos a las actualizaciones de la store.store.subscribe(() => { const state = store.getState(); console.log(state); });Aquí, le hemos pasado un callback que registra el valor del estado en la consola.Para actualizar el estado, despachamos(dispatch) una acción:store.dispatch({ type: "SET_VALUE", payload: "New value", });Aquí pasamos un objeto que representa la acción(action). Se requiere que cada acción tenga el campo de type y opcionalmente, payload.Por lo general, en lugar de crear acciones en el lugar, las personas definen action creator functions:const setValue = (value) => ({ type: "SET_VALUE", payload: value, });Y esta es la esencia de Redux.¿Por qué no podemos usar el hook useReducer en lugar de Redux?Desde la versión 16.8, React admite Hooks. Uno de ellos, useReducer, funciona de manera muy similar a Redux.Es fácil administrar el estado de la aplicación usando una combinación de useReducer y React Context API.Entonces, ¿por qué necesitamos Redux si tenemos una herramienta nativa que también nos permite representar el estado como un reductor? Si lo ponemos a disposición en toda la aplicación mediante la API de contexto, ¿no será suficiente?Redux ofrece algunas ventajas importantes:Herramientas del navegador: pueded usar Redux DevTools para depurar tu código Redux. Est nos permite ver la lista de acciones enviadas, inspeccionar el estado e incluso viajar en el tiempo. Puede alternar en el historial de acciones y ver cómo el estado se ocupó de cada uno de ellos.Manejo de efectos secundarios: con useReducer, debes inventar tus propias formas de organizar el código que realiza las solicitudes de red. Redux proporciona la API de middleware para manejar eso. Además, existen herramientas como Redux Thunk que facilitan aún más esta tarea.Pruebas: como Redux se basa en funciones puras, es fácil de probar. Todas las pruebas se reducen a verificar la salida con las entradas dadas.Patrones y organización de código: Redux está bien estudiado y hay recetas y mejores prácticas que puede aplicar. Existe una metodología llamada Ducks que puedes usar para organizar el código Redux.Construyendo con ReduxAhora que ha visto ejemplos de lo que hace Redux y cómo funciona, está listo para usarlo en un proyecto real.Profile@khriztianmorenoHasta la próxima

Una mejor manera de crear bibliotecas de componentes React

2022-07-05
reactjavascriptweb-development

Hoy repasarémos rápidamente cuatro patrones de programación que se aplican a los componentes compartidos en React.ReactEl uso de estos permite crear una biblioteca de componentes compartidos bien estructurada. El beneficio que obtiene es que los desarrolladores de tu organización pueden reutilizar fácilmente los componentes en numerosos proyectos. Tú y tu equipo serán más eficientes.Patrones comunesEn este post, te muestro cuatro patrones de API que puede usar con todos sus componentes compartidos. Estos son:JSX children pass-throughReact fowardRef APIJSX prop-spreading cont TypeScriptOpinionated prop defaultsPatrón 1: JSX Children Pass-ThroughReact ofrece la posibilidad de componer elementos utilizando la prop children. El diseño de componentes compartidos se apoya en gran medida en este concepto.Permitir que los consumidores proporcionen el children siempre que sea posible les facilita proporcionar contenido personalizado y otros componentes. También ayuda a alinear las API de componentes con las de los elementos nativos.Supongamos que tenemos un componente Button para empezar. Ahora permitimos que nuestro componente Button represente sus children, de la siguiente manera:// File: src/Button.tsx export const Button: React.FC = ({ children }) => { return <button>{children}</button>; };La definición de React.FC ya incluye a children como una prop válida. Lo pasamos directamente al elemento de botón nativo.A continuación, un ejemplo con Storybook para proporcionar contenido al Button.// File: src/stories/Button.stories.tsx const Template: Story = (args) => ( <Button {...args}>my button component</Button> );Patrón 2: forwardRef APIMuchos componentes tienen una asignación de uno a uno a un elemento HTML. Para permitir que los consumidores accedan a ese elemento subyacente, proporcionamos una prop de referencia utilizando la API React.forwardRef().No es necesario proporcionar un red para el desarrollo diario de React, pero es útil dentro de las bibliotecas de componentes compartidos. Permite una funcionalidad avanzada, como colocar una información sobre herramientas en relación con nuestro Button con una biblioteca de posicionamiento.Nuestro componente Button proporciona un solo HTMLButtonElement (button). Le proporcionamos una referencia con forwardRef().// File: src/buttons/Button.tsx export const Button = React.forwardRef < HTMLButtonElement > (({ children }, ref) => { return <button ref={ref}>{children}</button>; }); Button.displayName = "Button";Para ayudar a los consumidores de TypeScript a entender qué elemento se devuelve desde el objeto ref, proporcionamos una variable type que representa el elemento al que lo estamos pasando, HTMLButtonElement en este caso.Patrón 3: JSX Prop-SpreadingOtro patrón que aumenta la flexibilidad de los componentes es la propagación de props. La propagación de props permite a los consumidores tratar nuestros componentes compartidos como reemplazos directos para sus contrapartes nativas durante el desarrollo.La propagación de props ayuda con los siguientes escenarios:Proporcionar props accesibles para cierto contenido.Agrega atributos de datos personalizados para pruebas automatizadasUtiliza un evento nativo que no esta definido en nuestras props.Sin propagación de props, cada uno de los escenarios anteriores requeriría que se definieran atributos explícitos. La propagación de props ayuda a garantizar que nuestros componentes compartidos permanezcan tan flexibles como los elementos nativos que utilizan internamente.Agreguemos propagación de props a nuestro componente Botón.// File: src/buttons/Button.tsx export const Button = React.forwardRef< HTMLButtonElement, React .ComponentPropsWithoutRef<'button'> >(({ children, ...props }, ref) => { return ( <button ref={ref} {...props}> {children} </button> ); });Podemos hacer referencia a nuestras props restantes con la sintaxis de propagación y aplicarlos al botón. React.ComponentPropsWithoutRef es una utilidad de tipos que ayuda a documentar los props válidos para un elemento de botón para nuestros consumidores de TypeScript.Algunos ejemplos de esta verificación de tipos en acción:// Pass - e is typed as // `React.MouseEventMouseEvent>` <Button onClick={(e) => { console.log(e) }} /> // Pass - aria-label is typed // as `string | undefined` <Button aria-label="My button" /> // Fail - type "input" is not // assignable to `"button" | // "submit" | "reset" | undefined` <Button type="input" />Patrón 4: Valores predeterminados con opinionesPara ciertos componentes, es posible que desee asignar atributos predeterminados a valores específicos. Ya sea para reducir errores o mejorar la experiencia del desarrollador, proporcionar un conjunto de valores predeterminados es específico para una organización o equipo. Si encuentra la necesidad de predeterminar ciertas props, debe asegurarse de que aún sea posible para los consumidores anular esos valores si es necesario.Una complejidad común que se encuentra con los elementos button es el tipo de valor predeterminado, "submit". Este tipo predeterminado a menudo envía formularios circundantes accidentalmente y conduce a escenarios de depuración difíciles. A continuación, le mostramos cómo establecemos el atributo "button" de forma predeterminada.Actualicemos el componente Button para devolver un botón con el tipo actualizado.// File: src/buttons/Button.tsx return ( <button ref={ref} type="button" {...props}> {children} </button> );Al colocar las props predeterminadas antes de la difusión de props, nos aseguramos de que cualquier valor proporcionado por los consumidores tenga prioridad.Mira algunas bibliotecas de código abiertoSi está creando una biblioteca de componentes para tu equipo, eche un vistazo a las bibliotecas de componentes de código abierto más populares para ver cómo utilizan los patrones anteriores. Aquí hay una lista de algunas de las principales bibliotecas de componentes de React de código abierto para examinar:Ant DesignRainbow UIGrommetProfile@khriztianmorenoHasta la próxima

Design Systems con ReactJS y Storybook

2020-03-05
javascriptreactstorybookdesign-system

Documentar y probar tus componentes de React de forma aislada utilizando Storybook.Storybook ReactStorybook Reacttl;dr: En esta entrada, aprenderemos cómo configurar toda la infraestructura necesaria para construir un sistema de diseño de componentes reutilizables en React, utilizando Storybook.*Comencemos por entender que un sistema de diseño es una serie de componentes que se pueden reutilizar en diferentes combinaciones. Los sistemas de diseño te permiten gestionar el diseño. Si vamos a a designsystemsrepo.com podrá ver los sistemas de diseño utilizados por algunas de las compañías más grandes y las marcas más sólidas, como Priceline, Apple, IBM, WeWork, GitHub e incluso el gobierno de los EE. UU.Los sistemas de diseño pueden ser un importante multiplicador de la productividad en cualquier proyecto o empresa de tamaño mediano a grande, ya que podemos documentar nuestros componentes a medida que los desarrollamos, garantizando una apariencia y sensación coherente en todas las pantallas, y teniendo un flujo de trabajo continuo entre diseñadores y desarrolladores.<iframe width="100%" height="315" src="https://www.youtube.com/embed/guteTaeLoys?si=_8X6KwUOZCjQvwan" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>A lo largo de este video, construiremos progresivamente un sistema de diseño muy simple que contiene un solo botón, pero mostraré varias de las funciones que Storybook puede ofrecer para mejorar nuestra experiencia de desarrollado y la velocidad del proyecto.Aprendermos a configurar los StoryBook utilizados en la producción por todos, desde Lonely Planet hasta Uber, pero al mismo tiempo, lo mantendremos lo más simple posible, para que podamos reutilizar estas API para nuestras necesidades futuras.¡Espero que esto haya sido útil y/o te haya hecho aprender algo nuevo!Profile@khriztianmoreno �

¿Qué es un “side effect”?

2020-02-20
javascriptreactredux

En el anterior post, conocimos un poco sobre la inmutabilidad y la razon de porque deberia importarnos a la hora de escribir nuestro codigo en especial nuestros reducers.En esta ocasion, quiero abordar un poco sobre los *side effect *y como el trabajar con funciones puras nos puede servir, sin embargo, primero veamos qué hace que una función sea pura y porque está muy relacionada con la inmutabilidad.Reglas de inmutabilidadPara ser pura, una función debe seguir estas reglas:Una función pura siempre debe devolver el mismo valor cuando se le dan las mismas entradas.Una función pura no debe tener ningún efecto secundario (side effect).Los “side effects” son un término amplio, pero básicamente significa modificar cosas fuera del alcance de esa función inmediata. Algunos ejemplos de efectos secundarios …Mutar/modificar parámetros de entrada, como giveAwesomePowers (funcion del post anterior)Modificación de cualquier otro estado fuera de la función, como variables globales, o document.(anything) o window.(anything)Hacer llamadas a la APIconsole.log()Math.random()Las llamadas a la API pueden sorprenderte. Después de todo, hacer una llamada a algo comofetch('/users')podría no cambiar nada en su UI.Pero pregúntate esto: si llamó fetch('/users'), ¿podría cambiar algo en cualquier lugar? ¿Incluso fuera de tu UI?Sí. Creará una entrada en el registro de red del navegador. Creará (y quizás luego cerrará) una conexión de red al servidor. Y una vez que esa llamada llega al servidor, todas las apuestas están desactivadas. El servidor podría hacer lo que quiera, incluyendo llamar a otros servicios y hacer más mutaciones. Por lo menos, probablemente colocará una entrada en un archivo de registro en algún lugar (que es una mutación).Entonces, como dije: “side effect” es un término bastante amplio. Aquí hay una función que no tiene side effects:Puedes llamar esta función una vez, puedes llamarla un millón de veces y nada cambiará. Quiero decir, técnicamente, esto satisface la Regla 2. Llamar a esta función no causará directamente ningun efecto secundario.Además, cada vez que llame a esta función como add(1, 2) obtendrá la misma respuesta. No importa cuántas veces llame a add(1, 2) obtendrá la misma respuesta. Eso satisface la Regla 1: las mismas entradas == mismas respuestas.JS Array métodos que mutanCiertos métodos de vector mutarán el vector en el que se utiliza:push (agregar un item hasta el final)pop (eliminar un item del final)shift (eliminar un item desde el principio)unshift (agregar un item desde el principio)sortreversespliceLas funciones puras solo pueden llamar a otras funciones purasUna posible fuente de problemas es llamar a una función no pura desde una pura.La pureza es transititiva y es todo o nada. Puede escribir una función pura perfecta, pero si la finaliza con una llamada a alguna otra función que eventualmente llame a setStateo dispatch o cause algún otro tipo de efecto secundario … entonces todas las apuestas estarán desactivadas.Ahora, hay algunos tipos de efectos secundarios que son “aceptables”. Registrar mensajes con console.log está bien. Sí, técnicamente es un efecto secundario, pero no va a afectar nada.A Pure Version of giveAwesomePowersAhora podemos reescribir nuestra función teniendo en cuenta las Reglas.giveAwesomePowers — Pure functiongiveAwesomePowers — Pure functionEsto es un poco diferente ahora. En lugar de modificar a la persona, estamos creando una persona completamente nueva.Si no ha visto Object.assign, lo que hace es asignar propiedades de un objeto a otro. Puede pasarle una serie de objetos, y los combinará, de izquierda a derecha, mientras sobrescribe cualquier propiedad duplicada.(Y por “de izquierda a derecha”, quiero decir que la ejecución de Object.assign(result, a, b, c) copiará a en result, luego b, luego c).Sin embargo, no hace una fusión profunda(deep merge): solo se moverán las propiedades secundarias inmediatas de cada argumento. También, lo más importante, no crea copias o clones de las propiedades. Los asigna tal como están, manteniendo las referencias intactas.Entonces el código anterior crea un objeto vacío, luego asigna todas las propiedades de person, a ese objeto vacío y luego asigna la propiedad specialPower a ese objeto también. Otra forma de escribir esto es con el operador de propagación de objetos (spread):giveAwesomePowers — ES6 || spreadgiveAwesomePowers — ES6 || spreadPuedes leer esto como: “Cree un nuevo objeto, luego inserte las propiedades de person, luego agregue otra propiedad llamada specialPower”. Al escribir estas líneas, esta sintaxis spread es oficialmente parte de la especificación de JavaScript en ES2018.Funciones puras devuelven nuevos objetos a estrenarAhora podemos volver a ejecutar nuestro experimento desde antes, utilizando nuestra nueva versión pura degiveAwesomePowers.La gran diferencia es que esa person no fue modificada. Mafe no ha cambiado. La función creó un clon de Mafe, con todas las mismas propiedades, además de la capacidad de hacerse invisible.Esto es una especie de cosa extraña acerca de la programación funcional. Los objetos se crean y destruyen constantemente. No cambiamos a Mafe; creamos un clon, modificamos su clon y luego reemplazamos a Mafe con su clon.¡Espero que esto haya sido útil y/o te haya hecho aprender algo nuevo!Profile@khriztianmoreno �

¿Qué es la inmutabilidad?

2020-02-10
javascriptreduxreact

Inmutabilidad en React y ReduxLa inmutabilidad puede ser un tema confuso, y aparece en todas partes en React, Redux y JavaScript en general.Es posible que hayas encontrado errores en los que tus componentes de React no se vuelven a renderizar, a pesar de que sabes que has cambiado las props, y alguien dice, “Deberías estar haciendo actualizaciones de estado inmutables.” Tal vez tú o uno de tus compañeros de equipo escribe regularmente reducers en Redux que mutan el estado, y nos toca corregirlos constantemente (los reducers, o a nuestros compañeros de trabajo 😄).Es complicado. Puede ser muy sutil, especialmente si no estás seguro de qué buscar. Y sinceramente, si no estás seguro de por qué es importante, es difícil preocuparse.

Introducción a Apollo Client con React para GraphQL

2020-01-30
javascriptreactgraphqltutorial

GraphQL se ha vuelto popular recientemente y es probable que reemplace la API Rest. En este tutorial, utilizaremos el Cliente Apollo para comunicarnos con la API GraphQL de GitHub. Integraremos Apollo Client con ReactJS, pero también puede usarlo con otras plataformas (VueJS, Angular, etc).

Flux Standard Action (FSA)

2020-01-20
reactjavascriptreduxtutorial

Es una especificación ligera que define la estructura de una acción, para ser implementada en librerías que usan el patrón o arquitectura Flux.El cumplimiento de FSA ayuda a los desarrolladores a crear abstracciones que pueden funcionar con diferentes implementaciones de Flux.Flux Standard Action — ExampleFlux Standard Action — ExampleTodo inicia después de que Facebook publicó su arquitectura/patrón Flux, muchas librerías implementaron la filosofía Flux, Redux fue una de ellas.Flux se puede dividir en varios conceptos Dispatcher, Store, Action y View. Pero en este post vamos a conocer la parte de Action y como trabajar con estas de una forma mas estandarizada, para mas adelante poder hacer uso de otras librerías que implementan la filosofía FSA.Antes de adentrarnos mas en el tema principal de hoy, conozcamos el concepto de Action y como es definido por flux:Actions define the internal API of your application. They capture the ways to interact with your application. They are simple objects that consist of a “type” field and data.La especificación conduciría al siguiente objeto:{ type: 'ADD_TODO', text: 'TODO content' }El único problema con este ejemplo simple es que el desarrollador puede elegir cualquier nombre de propiedad para los valores. Todos los siguientes nombres son válidos: título, nombre, texto, todoNombre, etc. Es imposible saber qué propiedades esperar del ADD_TODO en el reductor de Redux.Sería mucho más fácil trabajar con acciones de Flux, si pudiéramos hacer ciertas suposiciones sobre su forma. Tal vez la definición de un estándar común mínimo para estos patrones permitiría tener la abstracción necesaria para comunicar nuestras acciones con el reducer. Esto es algo que Flux Standard Action (FSA) viene a resolver.Para entrar un poco en detalle sobre FSA, en necesario partir de la siguiente premisa que Flux Standard Action nos proporciona sobre las acciones:Una acción DEBE:ser un objeto JavaScript simple.tener una propiedad type.Una acción PUEDEtener una propiedad error.tener una propiedad payload.tener una propiedad meta.Una acción NO DEBE incluir propiedades que no sean type, payload, error, y meta.¿pero entonces que significa cada una de estas propiedades que nuestro objeto javascript puede llegar a contener?Veamos entonces cada uno de estostypeLa propiedad requerida type identifica la naturaleza de la acción que ha ocurrido al consumidor, type es una constante de tipo StringpayloadLa propiedad opcional payload PUEDE ser cualquier tipo de valor. Representa la carga de la acción. Cualquier información sobre la acción que no sea el type o el estado de la acción debe ser parte del campo payload.Por convención, el payload DEBERÍA ser un objeto.errorLa propiedad opcional error PUEDE establecerse en verdadero si la acción representa un error.An action whose error is true is analogous to a rejected Promise. By convention, the payload SHOULD be an error object.Si el error tiene cualquier otro valor además de true, incluyendo undefined y null, la acción NO DEBE ser interpretada como un error.metaLa propiedad opcional meta PUEDE ser cualquier tipo de valor. Está destinado a cualquier información adicional que no forme parte de payload .El concepto Flux Standard Action (FSA) es usado por algunas librerías que nos puede ayudar a reducir el texto repetitivo que debemos crear para nuestras accionesLibreríasredux-actions — un conjunto de helpers para crear y manejar acciones de FSA en Redux..redux-promise — Es un middleware que admite acciones de FSA.redux-rx — Utilidades RxJS para Redux, incluido un middleware que admite acciones de FSA.Espero en una próxima ocasión tener la posibilidad de dar una introducción de como reducir el Boilerplate de Redux con Redux-Actions.¡Espero que esto haya sido útil y/o te haya hecho aprender algo nuevo!Profile@khriztianmoreno �