Componentes React Polimórficos para el Cliente y el Servidor

This ad is not shown to multipass and full ticket holders
React Summit US
React Summit US 2025
November 18 - 21, 2025
New York, US & Online
The biggest React conference in the US
Learn More
In partnership with Focus Reactive
Upcoming event
React Summit US 2025
React Summit US 2025
November 18 - 21, 2025. New York, US & Online
Learn more
Bookmark
Rate this content

Explora los Componentes del Servidor a través de la lente de Componentes de IU reutilizables, donde todo "depende" de los requisitos individuales del caso de uso y las necesidades individuales de la aplicación. En lugar de luchar entre 'servidor' y 'cliente', tengamos lo mejor de ambos mundos.

This talk has been presented at React Summit US 2024, check out the latest edition of this React Conference.

Kiril Peyanski
Kiril Peyanski
10 min
22 Nov, 2024

Comments

Sign in or register to post your comment.
Video Summary and Transcription
Hola, mi nombre es Kirill y tengo una pequeña obsesión con los componentes de IU. Hablemos de React, específicamente de los Componentes del Servidor React 19. Te mostraré cómo construir una tabla de datos polimórfica utilizando componentes del servidor. Exploraremos la mezcla de componentes del servidor y del cliente y aplicaremos el patrón de composición. Discutiremos los componentes polimórficos y separaremos la lógica del cliente para renderizar componentes personalizados sin romper la funcionalidad del cliente. El componente se puede utilizar en diferentes entornos, transformándose en componentes del servidor o del cliente según corresponda. Esta charla se centra en la construcción de un componente polimórfico con un tamaño de paquete mínimo y acceso a las API tanto del servidor como del cliente.

1. Introducción a los Componentes del Servidor de React 19

Short description:

Hola, mi nombre es Kirill y tengo una pequeña obsesión con los componentes de UI. Hablemos de React, más específicamente, la nueva edición de React 19, los Componentes del Servidor. Cuando los Componentes del Servidor salieron inicialmente, prometieron un tamaño de paquete más pequeño, mejor rendimiento y una mejora en la obtención de datos. Hoy quiero mostrarte cómo construí lo que llamo una tabla de datos polimórfica, un componente único que se puede utilizar en el cliente y como un componente del servidor.

Hola, mi nombre es Kirill y tengo una pequeña obsesión con los componentes de UI. De hecho, hago esto a tiempo completo en Progress, construyendo la próxima generación de la biblioteca CanDo React. Durante mi tiempo libre, me encanta explorar el espacio del sistema de diseño, y actualmente estoy construyendo un marco de sistema de diseño al que llamo BackerUI.

Pero basta de mí. Hablemos de React, y más específicamente, la nueva edición de React 19, los Componentes del Servidor, que si me preguntas, deberían haberse llamado simplemente Componentes de React. Pero de todos modos, cuando los Componentes del Servidor salieron inicialmente, prometieron un tamaño de paquete más pequeño, un mejor rendimiento y una mejora en la obtención de datos, lo que me llevó a creer que debería reescribir toda mi interfaz de usuario para usar los Componentes del Servidor. Resultó ser una idea realmente mala, incluso Lee Robinson tuvo que tuitear que los componentes del cliente están bien. En algún momento, incluso tuve un botón del servidor. Se veía exactamente como un botón regular, pero era en su mayoría inútil porque no tenía un evento de clic. Terminé manteniendo mis componentes del cliente.

Pero en el camino, me di cuenta de que tenía una variante del cliente y del servidor de algunos de mis componentes. En teoría, una tabla de datos podría beneficiarse enormemente al ser un componente del servidor, pero aún necesitaba proporcionar interactividad para implementar paneles de control más dinámicos o carritos de compras de comercio electrónico. Hoy quiero mostrarte cómo construí lo que llamo una tabla de datos polimórfica, un componente único que se puede utilizar en el cliente y como un componente del servidor. Pero antes de eso, asegurémonos de que todos estemos visualizando lo mismo cuando pensamos en una tabla de datos. Una tabla de datos generalmente muestra datos tabulares. Puede tener un encabezado, un cuerpo, múltiples filas con celdas en su interior que muestran datos formateados. Genial. Ahora estamos en la misma página. Pero aún terminé con dos componentes de UI muy similares.

Una tabla de datos del servidor, que solo enviaba HTML al cliente, tenía acceso a mi sistema de archivos e incluso a una instancia de base de datos. Y un componente del cliente, que era interactivo. Podía editar, ordenar y filtrar los datos sin tener que volver al servidor y tenía acceso a las API del navegador y al DOM. Por lo general, si estuviera construyendo mis publicaciones de blog personales, estaría perfectamente bien tener dos componentes de UI muy similares con diferentes propósitos. Sin embargo, si eres como yo y estás construyendo una biblioteca de UI reutilizable, ya sea de código abierto o algo para otros equipos en tu organización, hay algunas cosas que debes considerar. Primero está la duplicación de código. Probablemente no quieras mantener dos bases de código separadas que hacen casi lo mismo, renderizando un par de filas con celdas en su interior. Segundo, está cómo los consumidores de tu biblioteca modificarían aún más para cumplir con sus requisitos. Muchas aplicaciones tienen necesidades individuales que pueden requerir una combinación de código del servidor y del cliente, personalizando todas las partes de tu componente en el camino. Y por último, los requisitos cambian. Siempre lo hacen.

Read also

2. Mezclando Componentes del Servidor y del Cliente

Short description:

Alguien que comienza con el componente del servidor debería poder agregar fácilmente interactividad más adelante sin tener que reemplazar todo el componente. Veamos cómo se vería el árbol de renderizado de una tabla de datos y veamos si podemos aplicar el patrón de composición allí. La mayor parte del árbol de renderizado no podrá utilizar componentes del servidor.

Alguien que comienza con el componente del servidor debería poder agregar fácilmente interactividad más adelante sin tener que reemplazar todo el componente. Ha surgido un patrón específico para ayudarnos a mezclar y combinar componentes del servidor y del cliente. Probablemente hayas visto este diagrama al hablar del patrón de composición.

Todo parece bien en teoría, pero a menudo se aplica a nivel de aplicación. Cuando nos enfocamos en el nivel del componente, las bibliotecas de UI suelen estar en modo cliente completo, lo que disminuye los beneficios de usar componentes del servidor. Veamos por un momento cómo se vería el árbol de renderizado de una data tabla y veamos si podemos aplicar el patrón de composición allí. Si has intentado implementar una tabla de data antes, rápidamente te darás cuenta de que necesitas código del cliente en casi cualquier parte del árbol. Ya sea para accessibility o para agregar una función simple de selección de filas, la mayor parte del árbol de renderizado no podrá utilizar componentes del servidor en absoluto.

Esto es problemático porque los consumidores de tu tabla de data aún pueden querer mantener parte del renderizado en el servidor. Pero según las reglas de los componentes del servidor, sabemos que si bien los componentes del servidor pueden renderizar componentes del cliente, lo contrario no es cierto. Sin embargo, hay una forma de lograr esto pasando todo a través de la propiedad de children pod, pero lo exploraremos en un minuto. Ahora, volvamos a nuestra tabla de data.

3. Componentes Polimórficos y Separación de la Lógica del Cliente

Short description:

Para renderizar una celda de markdown sin afectar el código del cliente, podemos usar un patrón llamado componente polimórfico. Siguiendo algunas reglas básicas, como no renderizar sus propios hijos y separar la lógica del cliente, podemos renderizar componentes personalizados en todo el árbol de componentes sin romper la funcionalidad del cliente. El árbol de renderizado debe consistir en nodos agnósticos que se puedan renderizar como componentes del cliente o del servidor. Las partes del cliente de un componente se extraen en una estructura de cliente, mientras que un componente de vista intermedio ensambla la ranura real y prepara a sus hijos. Al extraer toda la lógica del cliente en un componente separado y agregar un sufijo de cliente a su nombre, podemos evitar el renderizado del componente sin afectar el árbol y consumir el contexto del cliente en otros componentes.

Mi ejemplo favorito es una tabla de API que muestra documentación para un componente de UI o software de cualquier tipo. Para que todo sea legible y hermoso, a veces estamos renderizando markdown con bloques de código en su interior, pero las bibliotecas de markdown son pesadas y a menudo terminan en tu paquete del cliente. Es aún peor si quieres resaltar la sintaxis para los bloques de código.

Lo que quiero poder hacer es renderizar una celda de markdown sin afectar el código del cliente. Sé que hay otras formas de lograr esto, pero la implementación más sencilla para mí sería algo como esto, pasando una celda especializada que haga todo el trabajo sin afectar negativamente el paquete del cliente.

Ahora, profundicemos en cómo podemos lograr esto utilizando un patrón que he llamado componente polimórfico, un componente que puede renderizar cualquiera de sus nodos tanto en el cliente como en el servidor. Para lograr esto, simplemente debemos seguir algunas reglas básicas. Primero, los componentes no deben renderizar sus propios hijos. Y segundo, su lógica del cliente debe estar separada.

Con esas dos reglas simples, podremos renderizar componentes personalizados en todo el árbol de componentes sin romper la funcionalidad del cliente y aún así poder convertirnos en un componente completamente del cliente para aplicaciones que no admiten o no requieren componentes del servidor. Si aplicamos esas reglas correctamente, el árbol de renderizado debería verse algo así. Cada nodo en el árbol es agnóstico, lo que significa que se puede renderizar tanto como un componente del cliente como del servidor. Además, las partes del cliente de un componente se extraen en una estructura de cliente donde no afectan el renderizado del componente original.

Ahora repasemos la primera regla de no ser responsable de tus propios hijos en el contexto de los componentes de UI, por supuesto. Si anteriormente nuestro componente raíz de la tabla de datos estaba renderizando directamente el rol, ahora estamos introduciendo un componente intermedio. Aún no he encontrado un buen nombre para ellos, pero por ahora los llamo componentes de vista. La idea de un componente de vista es ensamblar la ranura real que se puede personalizar, en nuestro caso el rol, y preparar a sus hijos para que si el rol necesita ser un componente del cliente o del servidor, sus hijos, las celdas, no se vean afectados por esta decisión, lo que les permite ser cualquier cosa según los requisitos de la aplicación.

Volviendo a nuestro caso de uso con la celda de markdown, el patrón de renderizado nos permitiría renderizar un componente del servidor en una hoja sin importar cualquier otra personalización que hayamos realizado en el árbol. Ahora pasemos a nuestra segunda regla. Eventualmente, tú o tu gerente de producto querrán agregar una función simple de selección de roles y no les importará mucho la implicación de rendimiento si llevamos todo el componente al cliente.

Cuando estaba jugando por primera vez con los componentes del servidor, pensé que simplemente podía agregar cualquier cosa de React a un componente y funcionaría en el servidor en lugar del cliente. Pero si intentas agregar estado a un componente, que podría renderizarse en el servidor, como nuestras partes agnósticas de la tabla de datos, rápidamente te encontrarás con un error. Lo mismo ocurre al adjuntar eventos DOM, porque ¿cómo más sabrías cómo cambiar el estado? Entonces, lo que estamos viendo en la pantalla ahora no funciona.

Para que funcione, debemos extraer toda la lógica del cliente en un componente separado. Una vez más, el mejor nombre que se me ocurrió es agregar 'cliente' al final del nombre del componente. Esto nos permite evitar el renderizado del componente sin afectar directamente el árbol y solo proporcionar el contexto del cliente. Esto nos permite consumir este contexto desde la parte del cliente de nuestros otros componentes. Nuevamente, solo agregando lógica específica del cliente.

En nuestro caso de uso, eso sería la parte del cliente del rol, que solo debe agregar un evento de clic y agregar un nombre de clase si el estado del cliente indica que el rol está seleccionado. Ampliando la vista para ver la imagen completa, nuestros componentes móviles se ven así, renderizando de izquierda a derecha y su lógica del cliente se extrae en un componente separado con la directiva 'cliente'.

4. Using the Component in Different Environments

Short description:

Cuando se utiliza este componente en una aplicación cliente regular, sus partes agnósticas se convierten en componentes del cliente. Sin embargo, en un entorno de componente de servidor React como Next.js o una aplicación Wacom, el componente agnóstico se convierte en componentes del servidor, dejando JavaScript en el servidor y enviando HTML. Las partes del cliente del componente se envían por separado. Esto concluye el proceso de construcción de un componente polimórfico con un tamaño de paquete mínimo y acceso a las API tanto del servidor como del cliente. Sígueme en Twitter o X y echa un vistazo a mi trabajo en componentes polimórficos para Gendo React y el marco de diseño de sistema de código abierto Baka.UI.

Ahora, intentemos adivinar qué sucede si usamos este componente en una aplicación cliente regular, por ejemplo, una aplicación Create React o una aplicación Vite. El componente no funciona correctamente, ya que sus partes agnósticas se convierten en componentes del cliente. Nuestros componentes aún no funcionarán, pero eso depende de los frameworks subyacentes, no de nuestro componente.

Sin embargo, si consumimos nuestro componente en un entorno de componente de servidor React a la derecha, como Next.js o una aplicación Wacom, podríamos esperar que nuestro componente agnóstico se convierta en componentes del servidor, dejando su JavaScript en el servidor y solo enviando o transmitiendo, si prefieres, el HTML que han producido. Las partes del cliente de nuestro componente se envían en un paquete separado ya que las hemos separado del componente en sí.

Con esto, concluimos nuestro proceso de construcción de un único componente polimórfico que puede ser utilizado como componente del cliente o como componente del servidor o cualquier cosa intermedia, en realidad, con un tamaño de paquete mínimo, interactividad y acceso a las API tanto del servidor como del cliente desde sus partes correspondientes. Gracias por ver. Si te ha gustado esta charla, puedes seguirme en Twitter o X, si lo prefieres. Si quieres ver mi trabajo, actualmente estoy construyendo componentes polimórficos para Gendo React y también puedes echar un vistazo a mi marco de diseño de sistema de código abierto, Baka.UI. ¡Adiós!

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Escalando con Remix y Micro Frontends
Remix Conf Europe 2022Remix Conf Europe 2022
23 min
Escalando con Remix y Micro Frontends
Top Content
This talk discusses the usage of Microfrontends in Remix and introduces the Tiny Frontend library. Kazoo, a used car buying platform, follows a domain-driven design approach and encountered issues with granular slicing. Tiny Frontend aims to solve the slicing problem and promotes type safety and compatibility of shared dependencies. The speaker demonstrates how Tiny Frontend works with server-side rendering and how Remix can consume and update components without redeploying the app. The talk also explores the usage of micro frontends and the future support for Webpack Module Federation in Remix.
Entendiendo la Arquitectura Fiber de React
React Advanced 2022React Advanced 2022
29 min
Entendiendo la Arquitectura Fiber de React
Top Content
This Talk explores React's internal jargon, specifically fiber, which is an internal unit of work for rendering and committing. Fibers facilitate efficient updates to elements and play a crucial role in the reconciliation process. The work loop, complete work, and commit phase are essential steps in the rendering process. Understanding React's internals can help with optimizing code and pull request reviews. React 18 introduces the work loop sync and async functions for concurrent features and prioritization. Fiber brings benefits like async rendering and the ability to discard work-in-progress trees, improving user experience.
Thinking Like an Architect
Node Congress 2025Node Congress 2025
31 min
Thinking Like an Architect
Top Content
In modern software development, architecture is more than just selecting the right tech stack; it involves decision-making, trade-offs, and considering the context of the business and organization. Understanding the problem space and focusing on users' needs are essential. Architectural flexibility is key, adapting the level of granularity and choosing between different approaches. Holistic thinking, long-term vision, and domain understanding are crucial for making better decisions. Effective communication, inclusion, and documentation are core skills for architects. Democratizing communication, prioritizing value, and embracing adaptive architectures are key to success.
Componentes de Full Stack
Remix Conf Europe 2022Remix Conf Europe 2022
37 min
Componentes de Full Stack
Top Content
RemixConf EU discussed full stack components and their benefits, such as marrying the backend and UI in the same file. The talk demonstrated the implementation of a combo box with search functionality using Remix and the Downshift library. It also highlighted the ease of creating resource routes in Remix and the importance of code organization and maintainability in full stack components. The speaker expressed gratitude towards the audience and discussed the future of Remix, including its acquisition by Shopify and the potential for collaboration with Hydrogen.
Composición vs Configuración: Cómo Construir Componentes Flexibles, Resilientes y a Prueba de Futuro
React Summit 2022React Summit 2022
17 min
Composición vs Configuración: Cómo Construir Componentes Flexibles, Resilientes y a Prueba de Futuro
Top Content
Today's Talk discusses building flexible, resilient, and future-proof React components using composition and configuration approaches. The composition approach allows for flexibility without excessive conditional logic by using multiple components and passing props. The context API can be used for variant styling, allowing for appropriate styling and class specification. Adding variants and icons is made easy by consuming the variant context. The composition and configuration approaches can be combined for the best of both worlds.

Workshops on related topic

IA a demanda: IA sin servidor
DevOps.js Conf 2024DevOps.js Conf 2024
163 min
IA a demanda: IA sin servidor
Top Content
Featured WorkshopFree
Nathan Disidore
Nathan Disidore
En esta masterclass, discutimos los méritos de la arquitectura sin servidor y cómo se puede aplicar al espacio de la IA. Exploraremos opciones para construir aplicaciones RAG sin servidor para un enfoque más lambda-esque a la IA. A continuación, nos pondremos manos a la obra y construiremos una aplicación CRUD de muestra que te permite almacenar información y consultarla utilizando un LLM con Workers AI, Vectorize, D1 y Cloudflare Workers.
Masterclass de alto rendimiento Next.js
React Summit 2022React Summit 2022
50 min
Masterclass de alto rendimiento Next.js
Workshop
Michele Riva
Michele Riva
Next.js es un marco convincente que facilita muchas tareas al proporcionar muchas soluciones listas para usar. Pero tan pronto como nuestra aplicación necesita escalar, es esencial mantener un alto rendimiento sin comprometer el mantenimiento y los costos del servidor. En este masterclass, veremos cómo analizar el rendimiento de Next.js, el uso de recursos, cómo escalarlo y cómo tomar las decisiones correctas al escribir la arquitectura de la aplicación.