Explorando la magia de las runas en Svelte 5

La versión candidata de Svelte 5 ya está disponible. Una de sus características más debatidas es la introducción de “runas” como otro enfoque para la reactividad en Svelte, que ya es famoso por su singular forma de declarar estados reactivos.

En este artículo, veremos cómo usar el nuevo sistema de runas para declarar estados reactivos, en qué se diferencia del sistema existente en Svelte 4 y algunos ejemplos para compararlos. Para continuar, es recomendable que ya estés familiarizado con Svelte y su configuración y uso.

Table
  1. Cambios en Svelte 5
    1. Fragmentos
    2. Actualizaciones del sistema de eventos
    3. Nuevas funciones de Svelte
    4. Discursos
  2. Reactividad en Svelte antes de las runas
  3. Entendiendo cómo funcionan las runas en Svelte 5
  4. Comparación de la reactividad en Svelte con y sin runas
    1. Las runas son más detalladas
    2. Las runas se sienten similares a otros frameworks.
    3. Las runas resuelven varios problemas con la reactividad.
    4. Las runas se sienten más semánticas
  5. Conclusión

Cambios en Svelte 5

Svelte 5 es una de las actualizaciones más esperadas del framework Svelte. Incorpora varios cambios a Svelte 4, incluyendo nuevas funciones y la eliminación de algunas antiguas. Repasemos algunos de los cambios más destacados.

Fragmentos

Svelte 5 ha añadido el concepto de fragmentos, código de marcado reutilizable dentro de un componente. Un fragmento es un componente dentro de otro componente.

¿Qué hace un diseñador de UI?

De forma similar a cómo usamos componentes para extraer código repetido en un solo lugar, los fragmentos nos permiten extraer marcado repetido dentro de un componente. Estos son locales para los componentes y deben definirse en el mismo archivo que el componente.

Los fragmentos pueden ayudar a reducir la duplicación de marcado dentro de un componente, lo cual sería útil cuando algo se repite varias veces dentro de un componente, pero no fuera de él. Sin embargo, tenga en cuenta que esto no justifica la extracción de un fragmento como componente dedicado.

Actualizaciones del sistema de eventos

El sistema de manejo de eventos de Svelte se ha actualizado drásticamente de dos maneras principales:

  • En lugar de utilizar on:directivas como on:hovero on:clickpara manejar eventos en componentes, ahora se supone que los controladores de eventos se pasan como propiedades y los nombres se cambian a onhovery onclickcorrespondientemente.
  • En lugar de crear eventos personalizados en componentes usando createEventDispatcher, ahora simplemente tomamos el controlador de eventos como un apoyo y lo usamos como una devolución de llamada cuando ocurre ese evento

Las directivas originales on:aún funcionan, pero ahora están obsoletas y se planea eliminarlas en alguna próxima versión importante de Svelte.

Comprender la gestión de cambios de Prosci

Nuevas funciones de Svelte

Svelte 5 presenta varias funciones nuevas que los desarrolladores pueden usar directamente. Por ejemplo, se proporcionan funciones para montar y desmontar manualmente un componente en un elemento DOM específico mount.unmount

Además, svelte/reactivityahora exporta clases map, set, datey url, que se pueden usar en lugar de las clases nativas de JavaScript y son reactivas de forma predeterminada.

Discursos

La introducción de runas es probablemente el cambio más comentado en Svelte 5. El nuevo sistema de runas ha generado reacciones tanto positivas como negativas en la comunidad. Analizaremos las runas en detalle en el resto de este artículo.

Reactividad en Svelte antes de las runas

Antes de ver las runas y cómo se pueden usar para la reactividad en Svelte 5, veamos brevemente cómo se gestiona el estado reactivo en Svelte 4.

Cómo usar todos los modos de fusión de Figma

La reactividad es una de las principales ventajas de cualquier framework frontend. Sin ella, tendríamos que rastrear manualmente dónde se usa un valor específico y luego actualizar manualmente el DOM cuando este cambia. Con ella, podemos marcar ciertos valores como “reactivos” y dejar que el framework se encargue del rastreo y las actualizaciones del DOM.



Los distintos frameworks gestionan la reactividad de distintas maneras. Por ejemplo, React utiliza Hooks en sus componentes funcionales, mientras que Vue utiliza referencias y objetos reactivos.

Una de las principales diferencias de Svelte es que permite definir estados reactivos como variables normales de JavaScript. Utiliza un compilador para detectar dependencias e inyectar código actualizado en el DOM cuando el valor cambia. Esto hace que las declaraciones de estado se parezcan a las declaraciones normales de JavaScript y facilita su uso.

Por ejemplo, si asignamos un valor a una variable de la siguiente manera:

Una descripción general de las operaciones comerciales
valor del scriptlet = 1;/script

Y luego use esto en nuestro marcado HTML:

El valor se em{valor}/em

Svelte rastreará nuestra valuevariable y actualizará automáticamente el DOM cada vez que cambiemos este valor en otro lugar, como por ejemplo:

botón al hacer clic={ ()={ valor += 1; } } ¡Haz clic en mí! /botón

Sin embargo, este enfoque tiene algunas limitaciones. Dado que los cambios se rastrean por asignación, no funciona tan bien con matrices y objetos. Por ejemplo:

sea ​​​​arr = [1,2,3];...ul{#cada arr como v} li{v}/li{/cada}/ulbutton on_click={ ()={ arr.push(0); } } ¡Haz clic en mí! /botón

Aquí, esperaríamos que la lista se actualizara con cada pulsación de botón, ya que actualizamos la matriz 0con cada clic. Sin embargo, al no haber asignación, el compilador no considera esto como una actualización y la lista no cambia.

Para que esto funcione, necesitamos agregar una asignación ficticia arr = arrdespués del push como esto:

botón al_hacer_clic={ ()={ arr.push(0); arr=arr; } } ¡Haz clic en mí! /botón

De igual forma, Svelte no rastrea la reactividad transitiva. Por ejemplo:

scriptlet x = 0;let ​​​​y = 5 * x;/script...h2{x} {y}/h2button on_click={ ()={ x = x+1; } } ¡Haz clic en mí 2! /button

Aquí, yse define usando x, y la actualización xidealmente también debería actualizar y. Sin embargo, Svelte no lo hace por defecto. Para que funcione, debemos usar una declaración reactiva como la siguiente:

$: y = 5 * x;

Si bien Svelte rastrea la mayor parte de la reactividad por sí solo, necesita ayuda en tales casos para asegurarse de que todos los dependientes se actualicen correctamente.

Entendiendo cómo funcionan las runas en Svelte 5

Para solucionar estos y otros problemas, Svelte 5 introdujo el concepto de runas. Funcionan como símbolos y proporcionan instrucciones al compilador sobre reactividad y dependencias. Las runas son, en esencia, funciones de JavaScript a las que el compilador de Svelte presta especial atención. También se pueden usar en un .svelte.jsarchivo.

Tenga en cuenta que las runas son opcionales en Svelte 5. En otras palabras, el enfoque anterior a la reactividad en Svelte funcionará como antes, y podremos usar runas de manera selectiva si queremos.

La runa más básica es la $stateruna. Esta es similar a la letdeclaración en Svelte 4 y marca una variable como un estado reactivo y modificable. Con esto, el primer ejemplo se actualizaría a:

script let valor = $estado(1);/scriptValor es em{valor}/em.button onclick={ ()={ valor += 1; } } ¡Haz clic en mí! /button

En lugar de que la letdeclaración misma marque la reactividad, ahora la $stateruna devuelve un objeto que emite señales al actualizarse. La actualización del valor con value +=1no cambia, pero usamos el nuevo sistema de eventos con en onclicklugar de on:click. Esto funciona exactamente igual que en el ejemplo de Svelte 4.

Una de las ventajas del sistema de runas es que también funciona sin problemas con matrices y objetos, a diferencia de las letdeclaraciones:

script let arr = $state([1,2,3]);/script...ul{#each arr as v} li{v}/li{/each}/ul...button onclick={ ()={ arr.push(0); } } ¡Haz clic en mí! /button

Esto actualizará correctamente la lista sin necesidad de la declaración de asignación adicional.

Otra runa es la $derivedruna “`, que indica que la variable asignada se deriva de las variables de entrada y, por lo tanto, debe actualizarse cuando alguna de ellas cambia. Si actualizamos el ejemplo `xy` que vimos antes en Svelte 4 con esta runa, obtendríamos lo siguiente:

scriptlet x = $estado(0);let y = $derivado(5 * x)/scripth2{x} {y}/h2button onclick={ ()={ x = x+1; } } ¡Haz clic en mí 2! /botón

Aquí, en lugar de la $:…declaración, definimos yusando la $derivedruna. Esto indica que el valor de yse deriva usando xy debe actualizarse cuando xcambia. Aparte de esto, no hay ningún otro cambio, y la actualización xtambién se actualiza ycorrectamente.

Svelte 4 también incluía el concepto de sentencias reactivas, donde se $:anteponían sentencias como console.log(…)o if(…){…}. Esto indica que la sentencia debe volver a ejecutarse cada vez que se actualice alguna de las variables utilizadas en ella.

Solíamos usar sentencias reactivas en casos como la depuración de una actualización de variable, la realización de una llamada a la API para actualizar los resultados de una búsqueda, etc. Ahora, Svelte 5 incluye $effectrune, que realiza la misma función:

$efecto(()={consola.log(x,y);});

El compilador detectará las dependencias y ejecutará la devolución de llamada cada vez que se actualice cualquiera de ellas.



Para el caso de depuración, tenemos otra runa interesante llamada $inspect. Esta runa registra los valores que se le pasan cada vez que se actualizan. También podemos pasarle una llamada personalizada, que se invocará en lugar de registrar los valores.

Por ejemplo, en lugar de utilizar la $effectruna anterior, se puede lograr el mismo efecto de la siguiente manera:

$inspeccionar(x,y);

También puedes lograr esto usando una devolución de llamada personalizada:

$inspect(x,y).with((updateType,newX,newY)={ if(newY !== newX*5){ console.error("¡Algo está mal!"); }});

El primer argumento de la devolución de llamada es una cadena con un valor de inito update. Esto especifica si la devolución de llamada se ejecuta para inicializar la variable o para cambios posteriores en el valor. El resto de los parámetros son variables pasadas a en el $inspectmismo orden, con nuevos valores.

Comparación de la reactividad en Svelte con y sin runas

El nuevo sistema de runas de Svelte se ha debatido mucho en problemas, hilos de Reddit y otros medios. Como ya hemos mencionado, ha habido reacciones tanto positivas como negativas a este cambio. Pero desde que salió la versión candidata, las runas han llegado para quedarse, al menos en Svelte 5.

Comparemos el antiguo sistema de reactividad y las runas. Verás algunas de mis opiniones personales sobre el nuevo sistema, así que tenlo en cuenta.

Las runas son más detalladas

La sintaxis anterior para declaraciones reactivas utilizaba let .. = ..sentencias. En comparación, las runas son un poco más detalladas.

Sin embargo, al comparar las runas con los Hooks de React, no creo que sean demasiado detalladas. Los Hooks tienen un valor y una función de actualización independiente, mientras que las runas siguen utilizando actualizaciones normales basadas en asignaciones. Las runas se parecen bastante al sistema de referencias de Vue, pero con algunas diferencias significativas.

Las runas se sienten similares a otros frameworks.

Aunque no son como cualquier otro framework frontend de JavaScript, las runas, como ya he dicho, me recuerdan a los Hooks de React o a las referencias de Vue. Las sencillas declaraciones de valores reactivos, similares a las de JavaScript, de Svelte eran una de sus particularidades, por lo que este cambio parece hacer que Svelte se parezca un poco más a otros frameworks.

Aunque a algunos les pueda disgustar esta similitud, también tiene algunas ventajas. Por ejemplo, esta similitud podría facilitar el uso de Svelte para desarrolladores con más experiencia en otros frameworks. Como resultado, la introducción de runas podría facilitar la adopción de Svelte.

Las runas resuelven varios problemas con la reactividad.

Como se vio anteriormente, el compilador actual de Svelte presenta ciertos problemas con matrices y objetos. Si bien las runas podrían no resolver todos los problemas (por ejemplo, los objetos aún no son muy reactivos, solo superficiales), sí solucionan varios de los molestos problemas que se experimentan con mayor frecuencia al trabajar con matrices y objetos.

Además, las runas nos permiten usar la reactividad en .svelte.jslos archivos. Así, en lugar de tener que comprender y usar almacenes, podemos usar las primitivas de reactividad que se usan en el resto de la aplicación.

Además, las runas también ayudan con algunos problemas de rendimiento. Como se explica en la documentación de Svelte 5, al actualizar un elemento de una matriz, se invalidaba toda la matriz, no solo el elemento modificado. Ahora, con las runas, las actualizaciones pueden ser más precisas, ahorrando así tiempo de procesamiento y renderizado.

Las runas se sienten más semánticas

Actualmente, cualquier letdeclaración puede ser un estado reactivo que modifica y actualiza la aplicación. De igual forma, cualquier declaración $:…puede ser una dependencia, una declaración de depuración o un efecto secundario.

Con las runas, existen formas específicas de expresar estas intenciones. Por lo tanto, puedes estar más seguro de la intención detrás de las declaraciones con solo leer el código.

Conclusión

Las runas son una nueva incorporación a la próxima versión de Svelte 5, disponibles para su uso en la versión candidata. Si bien solucionan varios problemas de reactividad de Svelte, aún presentan algunos inconvenientes, como ocurre con cualquier cambio significativo en un framework.

¿Qué opinas de este cambio? ¡Cuéntamelo en los comentarios!

Gracias por leer. Puedes encontrar en la documentación de Svelte 5 y probar las runas en el entorno de juego de Svelte 5.

Si quieres conocer otros artículos parecidos a Explorando la magia de las runas en Svelte 5 puedes visitar la categoría Guias.

Entradas Relacionadas