Video Summary and Transcription
Starbeam es una biblioteca para construir interfaces de usuario reactivas con JavaScript, similar a Svelte, Vue y Ember. Proporciona una estructura de datos y una función de consulta para filtrar y ordenar. La función useStarBeam garantiza que la reconciliación JSX solo ocurra cuando cambian las dependencias reactivas. Starbeam realiza un seguimiento de cada operación de lectura y escritura para actualizar el componente en consecuencia. Se puede utilizar con React y otros frameworks, y ofrece herramientas de depuración e integración de localización.
1. Introducción a Starbeam
Hoy estoy aquí para hablarles sobre Starbeam, una biblioteca para construir interfaces de usuario reactivas con JavaScript. Starbeam no es el próximo y nuevo marco de JavaScript más popular. Tenemos ejemplos similares en Svelte, Vue y Ember. Comencemos echando un vistazo a la aplicación que vamos a construir. Tiene un formulario para crear nuevos usuarios, filtrar, eliminar elementos y más.
Hola a todos. Hoy estoy aquí para hablarles sobre Starbeam. Starbeam es una biblioteca para construir interfaces de usuario reactivas basada en el principio rector de que si escribes tu código reactivo como cualquier otro código, puedes construir interfaces de usuario radicalmente más simples y confiables con las habilidades de JavaScript que ya tienes.
Ahora, mucha gente ha dicho cosas similares antes, así que no los culpo por ser escépticos y desilusionados. Antes de comenzar, quiero ser muy claro acerca de algo. Starbeam no es el próximo y nuevo marco de JavaScript más popular. La demostración que haré hoy utiliza Starbeam dentro de una aplicación de React, y tenemos ejemplos similares en Svelte, Vue y Ember. Las personas que trabajan conmigo en Starbeam están bastante cansadas de la forma en que las nuevas ideas de front-end siempre se empaquetan con un nuevo marco al que debes migrar. Creemos que podemos hacerlo mejor, y espero que al finalizar aquí, haya despertado su interés.
Comencemos echando un vistazo a cómo se ve la aplicación que vamos a construir. Aquí está la aplicación terminada. Tenemos un formulario donde podemos crear nuevos usuarios. Puedo escribir leah-silver-portland. Puedo agregarlo. Como pueden ver, una vez que lo he agregado, hay información en la parte inferior sobre lo que sucedió. Puedo filtrar. Puedo escribir portland... aquí. Y cuando hago eso, verán que esto cambia a decir dos filtrados de cinco. Puedo eliminar elementos mientras estoy filtrado. Todo funciona como se esperaría. Puedo eliminar todos los elementos. Puedo volver a agregar personas. Así. Y eso es todo. Básicamente eso es lo que hace esta aplicación.
2. Estructura de datos y función de consulta
Comencemos usando la versión no finalizada de la demostración. Los datos que respaldan nuestro componente consisten en una tabla con filas y columnas. Cada fila representa a una persona con un nombre y una ubicación. Podemos agregar, eliminar y borrar filas. Además, podemos utilizar la función de consulta para implementar filtros y ordenamiento.
Bueno, lo primero que quiero hacer es cambiar a usar la versión no finalizada de la demostración. Así que empecemos por ahí.
De acuerdo, genial. Y como pueden ver, ya hay algunas características aquí, pero nada, no hay filtros. No hay nada que lo haga muy interesante. Y lo más importante, nada funciona aquí.
Antes de comenzar, echemos un vistazo a los datos que respaldan nuestro componente. Ahora es un poco complicado en términos de JavaScript, pero la razón por la que es complicado es menos porque a Starbeam le importe que hagas algo interesante aquí y más porque quiero mostrar que incluso si usas características de JavaScript avanzadas y sofisticadas, todo sigue funcionando.
Así que echemos un vistazo a la primera parte, que es la tabla. Una tabla tiene un ID que comienza en cero y eso es lo que podemos asignar como IDs a medida que creamos nuevas filas. Tenemos una lista de filas, que es un mapa de una cadena a una fila. ¿Qué es una fila? Bueno, aquí tenemos un ejemplo de una persona. Entonces, una persona tiene un nombre, que es una cadena, una ubicación, que es una cadena, y una fila es eso más un ID agregado. Así que vamos a mapear desde el ID hasta una fila de una persona, en este caso, y eso significa que será la persona más un ID. Vamos a tomar un montón de columnas para que tengamos una forma de crear encabezados de manera reflexiva. Vamos a tener un getter para las filas. Entonces, ¿qué hace el getter para las filas? Obtiene los valores de nuestro mapa y los expande en un array. Esto nos devuelve un array. ¿Cómo agregamos una fila? Bueno, creamos un nuevo ID como una cadena y luego creamos un nuevo objeto que contiene el ID y las columnas que especificamos, y luego establecemos el ID de cadena en el mapa y le damos la fila como valor, devolvemos la fila, cosas bastante básicas. ¿Cómo eliminamos un ID? Bueno, lo eliminamos de la fila. ¿Cómo borramos las filas? Borramos el mapa. Y luego hay una característica adicional aquí, que vamos a usar para implementar filtros, que es la función de consulta. Entonces, ¿qué es una consulta? Una consulta es otro objeto muy simple. Una consulta tiene una tabla que la respalda, y luego tiene un montón de filtros y un ordenamiento opcional. ¿Qué es un filtro? Es algo que toma una fila y devuelve un valor booleano. ¿Qué es un ordenamiento? Es algo que toma dos filas y te devuelve un número, que es lo que hacen las funciones de comparación. Bueno, ¿qué sucede si solicitas una lista de filas de una consulta? Bueno, lo primero que sucede es que obtenemos las filas de la tabla, y como recordatorio, eso hace esta expansión. Luego, recorremos todas las filas y nos aseguramos de que todos los filtros coincidan con la fila. Y luego, si tenemos un ordenamiento, ordenamos las cosas filtradas por el ordenamiento, de lo contrario, simplemente devolvemos el array. Básicamente es un pequeño objeto, envuelve una tabla, tiene algunos filtros y nos devuelve nuevas filas.
3. Estructura de datos, consulta y componente de la aplicación
Entonces, esa es la tabla y la consulta. La clase People tiene una tabla y una consulta. Hay dos métodos de conveniencia para ordenar y filtrar. El método de filtrado agrega un filtro a la consulta existente basado en el texto. El método de ordenamiento ordena los valores en la columna de la consulta utilizando la API de Intel y devuelve un nuevo objeto People. Lo importante a tener en cuenta es que no hay conceptos reactivos ni objetos especiales. Ahora, veamos la aplicación. Tenemos el gancho useStarBeam que envuelve el componente y permite acceder a los datos reactivos.
De acuerdo. Entonces, esa es la tabla, esa es la consulta. Y luego tenemos una pequeña clase People. Entonces, ¿qué es una People? Bueno, tiene una tabla de persona, tiene una consulta de persona. Y luego, ¿qué sucede si obtienes la tabla? Te devuelve la tabla. Si obtienes las filas de People, te devuelve las filas de la consulta. Y luego hay dos métodos de conveniencia para agregar ordenamiento y filtrado.
Veamos primero el filtrado. Puedes filtrar según el texto. Lo que hace es tomar la consulta existente, agregarle un filtro que verifica si el nombre de la fila incluye el texto o si la ubicación de la fila incluye el texto, y luego devuelve un nuevo objeto People con la tabla y la consulta. Luego, ¿qué hace el método de ordenamiento? Toma una columna, que puede ser un nombre o una ubicación, y luego toma una configuración regional. La razón por la que toma una configuración regional es porque vamos a querer usar la API de Intel para ordenar las cosas de manera que obtengamos el comportamiento correcto para diferentes idiomas. Y esto parece que hay muchas cosas sucediendo aquí, pero en realidad lo único que está sucediendo es que estamos creando un nuevo comparador para la configuración regional que pasamos, y luego le damos a la consulta un método de ordenamiento, que va a obtener los valores de la columna. Así que digamos que estamos ordenando por nombre, vamos a obtener el nombre y luego vamos a usar el comparador de intel.collator para comparar, y devuelve un nuevo objeto People para que cuando vayamos a obtener las filas, haga lo correcto.
Ahora, aquí está lo más importante. No tuviste que seguir necesariamente todo eso, pero lo que debes tener en cuenta es que no hay conceptos reactivos aquí. Esto es solo un objeto. La configuración regional es solo una cadena. No hay nada sobre ganchos. No hay nada sobre la necesidad de ejecutar algo varias veces. No hay ningún tipo especial de objetos que necesites. No hay tuberías. Hay un lugar donde hemos visto hasta ahora un objeto reactivo, que es justo aquí, este mapa reactivo. Pero aparte de eso, todo lo que hemos visto hasta ahora son solo funciones que trabajan con eso, en última instancia, con ese mapa subyacente y producen nuevos valores. De acuerdo, eso es básicamente cómo funciona la data en el fondo. Y ahora vamos a ir a ver nuestra aplicación. Ya hemos reemplazado la aplicación con la tabla data no finalizada, y ahora veamos el componente. Entonces, lo primero que notarás aquí es que tenemos este gancho useStarBeam y useStarBeam básicamente envuelve todo tu componente, y su trabajo es simplemente ponerte en modo StarBeam para que puedas acceder y trabajar con todos los datos reactivos de data. Ahora, dentro de StarBeam, dentro de un componente useStarBeam, hay dos secciones. Hay la sección superior, todo hasta el punto donde devuelves este fragmento JSX.
4. La función useStarBeam
La función useStarBeam tiene dos partes: la parte superior se ejecuta una vez para la configuración, y la parte inferior, un callback, se ejecuta repetidamente para la reconciliación JSX. StarBeam se asegura de que el callback solo se vuelva a ejecutar cuando cambian sus dependencias reactivas, similar a React.Memo.
Entonces, la parte superior de una función useStarBeam se ejecuta exactamente una vez, y es un buen lugar para configurar cosas como esta tabla que solo quieres configurar una vez o funciones que no quieres que cambien debajo de ti. Y la parte inferior, este callback, este fragmento de JSX, es lo que se ejecuta una y otra vez para que React tenga JSX para reconciliar. Pero lo importante aquí es que StarBeam se asegura de que no se vuelva a ejecutar si ninguna de las dependencias, las dependencias reactivas que se utilizan dentro del callback, se ejecutan. Y veremos lo que eso significa en un minuto. Puedes pensar en ello como un React.Memo potenciado.
5. Detalles de Implementación
Veamos la implementación real. Tenemos un formulario JSX que actualmente no funciona. Recorremos las columnas y las convertimos en THs. También hay una opción para borrar todas las filas. Recorremos las filas, creando TRs con TDs para el nombre y la ubicación de cada persona. También podemos eliminar filas individuales. Finalmente, la sección de resumen muestra el número total de elementos.
Veamos la implementación real aquí. Tenemos un JSX. Tenemos este formulario aquí. Y verás que si ejecutas el formulario, verás que el formulario no funciona realmente. ¿Verdad? Porque si miramos lo que hace la función append, no hace nada. Así que vamos a ver ese formulario en un segundo.
Luego recorremos todas las columnas de la tabla. Y, recuerda, las columnas son solo un campo que está en la tabla. Y las convertimos en THs. Y luego tenemos un último TH aquí que te permite borrar todas las filas. Y eso es lo que sucede si borro todas las filas. Hablaremos de eso en un segundo.
Luego recorro todas las filas que tengo. Y para cada una, creo un TR. Le doy la clave del ID que creamos. Y luego le doy TDs para la persona, el nombre y la ubicación. Y luego tengo una acción final aquí que me permite eliminar la persona.id. Solo quiero reiterar que cuando haces clic en, cuando miras borrar, eso solo hace rows.clear. Cuando hago Table.deletePersonId, eso solo hace rows.deleteId. Entonces, aunque estas son funciones de devolución de llamada que ocurren aquí dentro, están ocurriendo dentro de JSX, no tuviste que hacer nada especial aquí. Están funcionando con StarBeam data. OK.
Y finalmente, tenemos esta sección de resumen aquí. Y la sección de resumen tiene un atributo data items de la longitud. Y básicamente, cuando hay cero de ellos, hay un poco de CSS que hace que se vea diferente. Y luego tenemos un TD, que muestra el total. ¿Y cuál es el total? Ahora mismo, es muy simple. Solo dice items, dos puntos, Table.rows.length. OK, genial. Ahora, lo que quiero ver rápidamente aquí es, así que ya tenemos algunos datos interesantes aquí, ¿verdad? Si recargo y empiezo a borrar cosas, puedes ver que ya hay items 2 aquí.
6. Reactive State and Form Implementation
No tenemos ningún tipo de useState o arrays de dependencia. La forma en que funciona es que cuando obtienes las filas de la tabla, obtienes this.rows.values. StarBeam sabe que cuando haces this.rows.values, eso significa que estás leyendo la iteración de todo el mapa. No importa si usamos específicamente people.rows o si lo usamos a través de algo más. Cuando dices table.deletePerson.id, Starbeam sabe que esto invalida people.rows.length y vuelve a renderizar el JSX. Tenemos un formulario que no funciona con e.preventDefault. El formulario tiene un OnSubmit, campos de entrada para el nombre y la ubicación, y un botón de envío.
Puedes ver que el array se filtró y cosas así, ¿verdad? ¿Y cómo sucedió eso? ¿Qué sucedió exactamente aquí? Así que ten en cuenta que no tenemos ningún tipo de useState. No tenemos arrays de dependencia. No estamos usando realmente conceptos de React en absoluto. ¿Entonces, cómo funciona eso? La forma en que funciona es que si volvemos y miramos nuestra tabla, como dije, hay esta pequeña pieza de estado reactivo aquí. Y cuando obtienes las filas de la tabla, obtienes this.rows.values. Y StarBeam sabe que cuando haces this.rows.values, eso significa que estás leyendo la iteración de todo el mapa. Y eso significa que cada vez que algo cambia la iteración de todo el mapa, eso invalidará la lectura de this.rows.values.
Pero lo que sucede es que en realidad no usamos directamente las filas de la tabla la mayor parte del tiempo. Lo que hacemos principalmente es usarlo a través de otras abstracciones. Y veremos que eso se volverá cada vez más elaborado con el tiempo. Y así que el punto es que no importa si usamos específicamente people.rows aquí, o si lo usamos a través de algo más. El hecho de que accedamos a los data que está dentro de people.rows de alguna manera. Entonces people.rows, solo como recordatorio, en realidad no es directamente... No es la tabla, va a la consulta. Y la consulta, como recordatorio, va al filtro, ¿verdad? Así que en realidad hay muchos pasos entre lo que parece, oh, son solo las filas, y esa pieza de estado. Pero no tienes que decir nada al respecto. Puedes simplemente escribir código normal de JavaScript aquí.
Ok, eso es genial y todo. Y lo que eso significa básicamente es que cuando dices table.deletePerson.id, Starbeam sabe que esto invalida people.rows.length, y por lo tanto sabe que debe volver a renderizar la plantilla. No la plantilla, el JSX. Entonces, ¿qué es lo siguiente que queremos hacer? Bueno, tenemos un formulario que no funciona aquí en este append, así que vamos a implementarlo. Lo que tenemos ahora mismo es simplemente e.preventDefault. Echemos un vistazo rápido al formulario. Así que tenemos un formulario aquí, y tiene un OnSubmit. Y luego tenemos inputType="text", name="name". Así que estamos usando la forma HTML de darle un nombre. Estamos diciendo que es requerido. Hay algunas cosas de CSS aquí para los errores. Y el segundo campo de entrada tiene el nombre de una ubicación. Tenemos un buttonType="submit", ¿verdad? Así que eso simplemente significa que cuando presionamos Enter, presionamos Tab y Espacio, hacemos clic en lo que sea que vaya a presionar, llamará al Submit.
7. Form Data and Table Append
Para obtener los datos del formulario, extraemos el formulario y lo convertimos en un objeto utilizando form data. Este objeto contiene los nombres de campo válidos y sus valores correspondientes. Luego, utilizamos el método append para agregar las columnas de nombre y ubicación a la tabla. Después de eso, reiniciamos el formulario. Este proceso funciona porque Starbeam realiza un seguimiento de cada operación de lectura y escritura y actualiza el componente en consecuencia.
Entonces, ¿qué queremos hacer con eso? Bueno, lo primero que debemos hacer es obtener el formulario del evento. Y lo segundo que haremos es crear un nuevo formulario data a partir del formulario. Ahora, si no sabes qué es un formulario data, es bastante interesante. Básicamente, lo que hace es tomar el formulario, obtener todos los nombres de los campos que son válidos, en otras palabras, campos no deshabilitados y cosas así, y lo convierte en un objeto que tiene esas claves y esos valores. Y lo realmente genial de un formulario data es que implementa un iterable de entradas. Entonces, simplemente puedes decir object.fromEntries de un formulario data, y obtienes algo que se ve exactamente como esperarías. Es un poco de invocaciones aquí, pero tomamos un formulario, creamos un formulario data, hacemos object.fromEntries, y obtenemos esto. Obtenemos un objeto que tiene un nombre y una ubicación, que es precisamente lo que queremos. Nuestra tabla tiene un append en ella. El append toma columnas, que son el nombre y la ubicación. Y cuando terminamos con eso, reiniciamos el formulario para vaciar lo que ya hemos hecho. En este punto, esperaríamos que funcione, creo. Así que comprobémoslo. Voy a agregar Lea-Silber y voy a agregar Portland, y funcionó. Genial. Entonces, ¿por qué funcionó? ¿Qué sucedió exactamente aquí? Básicamente, lo que sucedió es que cuando hicimos clic en table.append, eso estableció una fila en el mapa aquí. Y porque otras partes de ese mismo componente leen, en última instancia, los this.rows.values aquí, que están en iteración, el hecho de que agregamos algo al mapa significa que invalidó a cualquiera que intentara leer, a cualquiera que se preocupara por la iteración, ¿verdad? En otras palabras, porque me preocupé, porque en algún momento calculé una lista de todas las claves y los valores, si las claves y los valores cambian, entonces cualquiera que lea la lista de claves necesita recalcular, ¿verdad? Entonces, el hecho de que llamé a append, parece que estoy simplemente mutando un objeto, Detrás de escena, Starbeam realiza un seguimiento de cada lectura, cada escritura y los vincula juntos. Genial.
8. Implementando el Filtro
Para implementar el filtro, necesitamos una celda para almacenar el valor del filtro. La consulta se basará en la tabla de personas y utilizará la función de filtro. Al acceder a filter.current, podemos modificar la celda con el valor actual del objetivo. Ahora, las filas devolverán las filas de la consulta en lugar de las filas de la tabla, asegurando que el componente dependa tanto del filtro como de las filas.
De acuerdo, ahora que hicimos eso, lo siguiente que probablemente queramos hacer es implementar el filtro. Para implementar el filtro, vamos a necesitar una celda. Una celda en Starbeam es simplemente un objeto muy simple que es un espacio para almacenar una cosa, ¿verdad? Tenemos una celda aquí, y es un espacio para almacenar una cadena porque el filtro va a tener una cadena en él.
Vamos a querer hacer otro campo aquí que simplemente será nuestro filtro. ¿Cómo se ve ese campo? Bueno, va a tener un valor predeterminado de filter.current, y filter.current está leyendo de esa celda, ¿verdad? Así que eso es una cosa, es una cosa reactiva, está leyendo de la celda. ¿Y qué sucede cuando escribes algo? No hay problema, establecemos el filtro, por lo que filter.set es cómo modificas una celda con el valor de el objetivo actual, ¿verdad? Entonces, ahora, si escribo algo, pude escribir en el filtro, pero aún no hemos hecho nada todavía, así que todavía necesitamos hacer algo aquí.
Para que sea útil, no queremos que las filas sean solo un montón de filas, queremos hacer una consulta, ¿verdad? ¿Cuál será la consulta? La consulta será la tabla de personas que tenemos, y vamos a usar esa función de filtro que escribimos antes para filtrar según filter.current. Ahora, ten en cuenta que simplemente acceder a filter.current aquí es suficiente para saber que estamos accediendo al filtro subyacente. Así que tenemos una función aquí llamada consulta, es una función regular, nada especial aquí, y estamos haciendo una nueva consulta, que filtra por lo que escribimos aquí, y también vamos a ordenar por la ubicación por si acaso.
De acuerdo, ahora que hicimos eso, simplemente vamos a actualizar las filas aquí para devolver las filas de la consulta en lugar de las filas de la tabla. Y ahora, si escribo algo, Portland, Yehuda, ¿verdad, si escribo Sherag, si escribo NYC, ¿verdad, todo eso funcionó. Y entonces, ¿por qué funcionó? Bueno, parte de por qué funcionó es que el filtro hace esta cosa algo complicada, ¿verdad, va y para cada fila, verifica si el nombre o la ubicación incluyen el texto. Y cuando dijimos query.rows, eso es lo que realmente fue y ejecutó el filtro, ¿verdad? Entonces, nuevamente, esto es solo código JavaScript bastante normal. Y todo lo que hicimos fue hacer una nueva función aquí llamada consulta. Y todo lo que hicimos fue hacer que nuestra función existente rows use la consulta. Pero el hecho de que este código aquí abajo, el código que hace un bucle sobre dice filas, el hecho de que eso accedió a la consulta, ¿qué significa eso? Significa que tiene una dependencia de dos cosas. Tiene una dependencia de esta cosa de filtro. Y también tiene una dependencia de esta cosa de filas, que tiene una dependencia en última instancia de las filas de la tabla, que es esta iteración. Entonces, básicamente, la forma normal de acceder, la forma normal de escribir código aquí significa que nuestro cálculo de filas aquí hizo que StarBeam supiera que todo este componente depende tanto del filtro como de las filas.
9. Agregando la Funcionalidad de Conteo de Elementos Filtrados
En esta parte, agregamos una funcionalidad para mostrar el número de elementos filtrados. Reemplazamos la función total para calcular el número de filas en la consulta y el número total de filas en la tabla. Si son iguales, devolvemos el valor anterior. De lo contrario, mostramos el número de elementos filtrados sobre el número total de elementos. Esta implementación demuestra cómo se rastrean y actualizan automáticamente las dependencias en Starbeam.
De acuerdo, algo que creo que vale la pena mencionar aquí es que sorprendentemente hay algunas piezas de estado raíz aquí para una configuración bastante complicada. Así que vamos a agregar una característica más aquí y lo que vamos a hacer es que vamos a hacer que si filtramos algo, esto no diga elementos para, queremos que diga elementos una cierta cantidad de filtrados sobre, ¿verdad? ¿Cómo vamos a hacer eso? Simplemente vamos a reemplazar esta función total aquí. Lo primero que vamos a hacer es obtener nuestras filas y eso va a ser la cantidad de filas que había en la consulta, ¿verdad? Y lo segundo que vamos a hacer es obtener el número total de filas en la tabla. Ahora, si las dos cosas son iguales, el contador de filtro y el contador total, devolvemos lo que teníamos antes. De lo contrario, decimos elementos cantidad filtrados sobre cantidad total, ¿verdad? Así que si simplemente recargamos la página, obviamente no pasa nada aquí. Pero si comenzamos a filtrar, decimos Gerog, decimos NYC, podemos ver que funcionó. Y una vez más, esta función total tiene una dependencia de las filas. Tiene una dependencia de table.rows, ¿verdad? Tiene una dependencia. ¿Y de qué depende rows? Depende de la consulta, que depende del filtro. Así que todo esto es simplemente una forma bastante natural de escribir código normal sin tener que escribir nada especial, sin tener que decir nada especial sobre cómo las cosas están conectadas entre sí. Y todo funciona de manera adecuada.
10. Herramienta de Depuración y Seguimiento de Dependencias
Ahora, permíteme mostrarte una herramienta de depuración en Starbeam que te permite ver las dependencias de manera más explícita. Al obtener el registrador de depuración de Starbeam y establecer el nivel del registrador en depuración, puedes abrir las herramientas de desarrollo y ver información adicional. La herramienta de depuración muestra las dependencias del bloque useStarBeam y te permite rastrear las invalidaciones. También puedes asignar nombres a las piezas del estado raíz para que la herramienta de depuración sea menos ruidosa.
De acuerdo. Ahora, sigo diciendo que las cosas son dependencias de otras cosas. Pero tienes que imaginarlo un poco. Pero déjame mostrarte una pequeña herramienta de depuración que tenemos que te permite verlo de manera más explícita. Y para activarla, simplemente vamos a obtener el registrador de Starbeam. Vamos a obtener el registrador de Starbeam debug. Debug. Vamos a decir que el nivel del registrador es igual a debug. Debug.
De acuerdo. Y ahora, una vez que hagamos eso, si abrimos las herramientas de desarrollo, veremos que comenzamos a obtener información adicional. Nos muestra que este bloque useStarBeam, que se encuentra aquí. Vamos a bajar eso. Puedes ver exactamente dónde se encuentra. Te dice que tiene una dependencia en esta celda, tiene una dependencia en este mapa. Lo haré un poco más pequeño.
De acuerdo. Ahora, lo siguiente que podemos hacer con esta herramienta de depuración es si invalidamos algo. Digamos que volvemos a este filtro aquí y decimos `ver`. Lo que veremos es que nos dice que useStarBeam se invalidó y nos dice exactamente qué se invalidó, que es esta celda aquí. Nos da un enlace a esta ubicación exacta. Ahora, esto es un poco ruidoso. Incorporado en esta configuración hay una forma de decir para cada nueva pieza de estado raíz, puedes darle un nombre. Aquí podemos decir celda, podemos darle un nombre de filtro. Y podemos ir a nuestra tabla y podemos decir que ya lo hice. Le di al mapa un nombre de tabla, ¿verdad? Y podemos ir, creo que esas son las únicas piezas de estado, ¿verdad? Así que ahora, si lo miramos, veremos que nos da los nombres en lugar de las palabras muy largas. Y si quieres activarlo y quieres ver las trazas de la pila de todos modos, los enlaces más largos para que puedas hacer clic en ellos, simplemente puedes activarlo siempre en modo de trazado. Y eso te dará los enlaces sin importar qué, ¿verdad? Así que lo abres y siempre tienes estos enlaces aquí, genial. Apaguémoslo, de acuerdo. Ahora tenemos una última característica que quiero implementar.
11. Integración de Localización y Ordenamiento
Queremos pasar la configuración regional directamente a nuestro componente. Para lograr esto, utilizamos el gancho useProp proporcionado por Starbeam React. Al cambiar la configuración regional del sistema a locale.current, podemos establecer un puente entre React y Starbeam. Esto nos permite ordenar las palabras de manera diferente según la configuración regional seleccionada, como se demuestra con la palabra 'name' en sueco.
Hasta ahora, todo está contenido dentro de StarBeam. Pero como dijimos, esto está dentro de una aplicación React. Y nos gustaría poder que este componente tome algunos argumentos de React. Entonces, en este caso, lo que quiero hacer, en lugar de usar solo la configuración regional del sistema como ordenamiento, quiero obtener la configuración regional de la aplicación React.
De acuerdo, para facilitar eso, creé un selector de configuración regional aquí. Lo vamos a implementar utilizando un patrón bastante normal de React, ¿verdad? Vamos a usar estado. Vamos a tomar algunas cosas aquí. Voy a formatear la configuración regional. Pero es un cuadro de selección, ¿verdad? Establece el estado. Y ahora que hicimos eso, si lo activamos aquí, ¿verdad? Y podemos ver que tenemos el cuadro de selección.
Y lo que nos gustaría poder hacer, es pasar la configuración regional directamente a nuestro componente. Y, por supuesto, no hay razón por la que no podamos hacerlo. Este es solo un componente regular de React. Entonces podemos decir props.locale string aquí. Pero hay un pequeño problema aquí, que es que la forma en que React funciona es que simplemente seguirá llamando a esta función una y otra vez con nuevas props, pero Starbeam realmente no tiene idea de qué se trata eso. Y realmente necesitamos una forma de convertir esta configuración regional en algo que Starbeam entienda. Y para este tipo de situación, hay un gancho que proporcionamos llamado useProp. Entonces podemos decir const locale = useProp props.locale. De acuerdo, vamos a importar useProp de Starbeam React. Y ahora todo lo que tenemos que hacer aquí es simplemente cambiar la configuración regional del sistema a locale.current, ¿verdad? Así que simplemente conectamos el mundo de React con el mundo de Starbeam.
Y ahora aquí está la razón por la que lo configuré de esta manera. Esta palabra no deseada, name, se ordena de manera diferente en sueco y otros idiomas. Así que cambiemos rápidamente al sueco. Y como puedes ver, ahora se ordena al final. Volvamos a abrir nuestras herramientas de desarrollo. Y ahora lo que podemos ver es que en realidad tenemos tres piezas de estado aquí. Tenemos esta celda, la celda de filtro.
12. Seguimiento de Dependencias y Bibliotecas Universales
Tenemos el Prop y el Map. La función tiene dependencias en filter, props y el Map. StarBeam realiza un seguimiento de estas dependencias y las invalida cuando cambian. Los componentes que utilizan StarBeam no se invalidan entre sí. StarBeam se puede utilizar con React y otros frameworks. Puedes escribir bibliotecas universales utilizando los conceptos y adaptadores de StarBeam. Ven a verlo en nuestro Discord y GitHub. Únete y ayuda con las herramientas de depuración y más.
Tenemos el Prop y tenemos el Map del que hemos estado hablando todo el tiempo. Y al igual que cualquier otra cosa, podemos darle un nombre. Así que vamos a llamarlo props.locale por conveniencia en nuestra depuración. Muy bien, ahora podemos ver, okay, tenemos esas tres cosas. Y ahora si selecciono sueco, puedes ver que eso es exactamente lo que lo invalidó, ¿verdad? Y si en lugar de eso escribo algo como NYC o algo así, lo que podemos ver es que ahora sabemos que el filtro es lo que lo invalidó.
Ahora esta es todavía una herramienta de depuración bastante temprana. Esto es solo un registro por conveniencia. Esperaríamos algunas herramientas de depuración más elaboradas construidas eventualmente sobre esta infraestructura. Pero la idea básica aquí es que desde la perspectiva de StarBeam, esta función aquí tiene dependencias de solo tres cosas. Ahora una de las cosas, el Map, es un poco elaborado para que podamos hacer un seguimiento más granular. Pero en general, solo hay tres piezas de estado raíz. No importa que tengamos esta función total, no importa que tengamos esta función rows, no importa que cuando vayamos y miremos esta función rows, esté haciendo este complicado proceso de múltiples pasos, esté haciendo este complicado proceso de filtros, nada de eso importa. Al final del día, lo único que realmente le importa a StarBeam es que tiene una dependencia en filter, tiene una dependencia en props, tiene una dependencia en el Map. Y cada vez que cambiamos algo, vamos a crear una nueva persona, ¿de acuerdo? Así que vamos a crear una nueva persona, vamos a crear a Leia de nuevo, y vamos a decir pdx, ¿de acuerdo? Lo que puedes ver es que lo que se invalidó es el Map, ¿de acuerdo? Así que al final del día, aunque hay mucha complejidad aquí en tu código, esa complejidad está en cosas muy estándar y normales de JavaScript. Y la reactividad realmente solo dice que este callback aquí, esta cosa que genera JSX, tiene una dependencia de tres cosas. Tiene una dependencia de un Map, de la iteración del Map. Tiene una dependencia de un filtro. Y tiene una dependencia de la configuración regional, la prop locale. Y ahora todo lo que StarBeam tiene que hacer es hacer un seguimiento de esas tres cosas. Cada vez que cambian, lo invalida y notifica a React y lo invalida.
Lo bueno de esto es que si tienes muchos componentes en tu aplicación que usan StarBeam, cada uno de ellos no invalida a los demás. Es como dije, es como un react.memo mejorado. Entonces lo que sucede es que sin que tengas que hacer nada, simplemente accediendo a los valores utilizando funciones normales, utilizando getters normales, utilizando métodos normales, utilizando patrones de acceso normales, le estás diciendo a StarBeam exactamente cuáles son las dependencias. Y StarBeam es capaz de hacer un seguimiento de exactamente cuándo necesita invalidar. Y también puedes integrarte fácilmente en el mundo de React, si es necesario, y eso funciona perfectamente bien.
Ahora, una cosa que es bastante genial, creo que la última cosa que quiero decir aquí, es que si vuelves y miras nuestra tabla, no hay importaciones reales de StarBeam React o de React, ¿verdad? Y eso se debe a que este código, este código de la tabla, este código de la consulta, este código de las personas, todo esto es puro StarBeam. Y eso significa que este mismo código funcionará en Svelte, funcionará en Vue, funcionará en Ember, y eso es bastante genial. Significa que puedes comenzar a escribir bibliotecas que sean algo así como este ejemplo de juguete, pero más grande, algo como una biblioteca GraphQL, y puedes escribirlo principalmente en StarBeam, en conceptos de StarBeam, y luego exponerlo a React, a Svelte, a Vue utilizando estos adaptadores. No tienes que construir código universal con StarBeam, simplemente puedes construir cosas dentro de la aplicación React, pero también podrías construir estas bibliotecas universales, y estoy muy emocionado de ver qué va a suceder una vez que el ecosistema tenga la capacidad de comenzar a escribir código reactivo de una manera que esté desacoplada de los frameworks individuales. Creo que eso va a ser realmente increíble. Si te emociona esto, definitivamente ven a verlo. Ven a nuestro Discord, puedes venir a nuestro GitHub, puedes comenzar, puedes darle me gusta, puedes enviar problemas, puedes intentar integrarlo, puedes intentar hacer algo de trabajo. Puedes intentar ayudar con las herramientas de depuración, hay muchas cosas sucediendo. Estoy muy emocionado por lo lejos que hemos llegado, pero todavía queda mucho por hacer. Y si eres el tipo de persona a la que le gusta involucrarse desde el principio y hacer algo, genial, únete, estamos emocionados de tenerte. Muchas gracias y disfruta el resto de tu conferencia. ♪♪♪
Comments