De esta manera, podrías obtener enormes beneficios de rendimiento, porque no estás haciendo ningún trabajo, no tienes que diferenciar nada para los cambios, porque ya sabes qué lugares en la aplicación necesitan ser actualizados. Por supuesto, esto tiene un costo. Frameworks como Solid o Angular y Vue con este próximo VaporMode ya intentan lograr esto, pero por supuesto tiene desventajas.
En primer lugar, en React si adoptaras signals en React, tendríamos que migrar a los componentes de ejecución única. Ya no tienes esta garantía de que un componente leerá y ejecutará, la función ya no se volverá a ejecutar cada vez que algo cambie, sino solo esas partes específicas en la aplicación cambian. Esto tiene, por supuesto, implicaciones masivas para lo que puedes y lo que no puedes hacer en el cuerpo de un componente. Será muy interesante ver cómo se desarrolla esta transición en algo como Angular o Vue, pero ya podemos echar un vistazo al resultado final en Solid.js que comenzó con signals desde el principio.
Además, agregué estos componentes de ejecución única entre comillas, porque no es realmente de ejecución única. Sí, el componente externo, la función externa, solo se ejecuta una vez para crear todos los effects, crear todas las signals, conectar todo junto, pero luego tienes dentro de tu componente todos esos diferentes lugares que se actualizan en varios momentos en el tiempo. Por ejemplo, aquí tenemos tres lugares, los dos effects y el lugar en el JSX, y todos esos lugares tienen que volver a ejecutarse en ciertos momentos. Incluso si tienes este modelo de solo crear tus componentes una vez inicialmente, ciertas partes de él se volverán a ejecutar una y otra vez dependiendo de las signals que se lean en esos ámbitos específicos. Esto puede volverse muy complicado muy rápidamente si tienes componentes complejos que leen de diferentes signals.
En el mundo de React, por otro lado, puedes simplemente colocar un console lock en algún lugar, porque sabes con certeza cuándo se ejecuta la primera línea del componente porque algo se volvió a renderizar, entonces la última línea del componente también tiene que volver a ejecutarse. Esto hace que este problema de que ciertos lugares se ejecuten fuera de orden y en varios momentos se vuelva más complicado cuanto más signals uses en la aplicación. Además, imaginemos que tenemos un componente aún más complejo y tal vez otro desarrollador vino y ahora comenzamos a mezclar las diferentes propiedades. Así que A, B y C son accessors como se llama en Solid para recuperar el valor o también podrían ser directamente signals. Tenemos el valor D, que es solo un número, un número simple que nunca cambiará. De repente, tenemos que manejar esos dos mundos de contenedores que contienen valores cambiantes y valores en sí mismos que ahora ya no pueden actualizarse, porque al final migramos al componente de ejecución única, por lo que solo se ejecuta una vez de arriba a abajo.
Todo lo que no es una signal no se actualizará y no puede actualizarse. Ahora estamos en este mundo donde cuando escribes un componente algunas propiedades están permitidas a cambiar mientras que otras, la propiedad D, no están permitidas a cambiar o los cambios simplemente serían ignorados. Por supuesto, en algo como Solid el compilador trabaja alrededor de esto un poco para que todas las propiedades que se pasan a un componente se envuelvan automáticamente para que todas las propiedades puedan cambiar. Sin embargo, todavía tienes el mismo problema al escribir algo como custom hooks o el equivalente de custom hooks, porque allí todavía necesitas especificar manualmente explícitamente qué argumentos pueden cambiar y qué argumentos no pueden cambiar. El mundo de React, por otro lado, asume que todo puede cambiar. Cada argumento y cada propiedad de tu función puede cambiar, y nos obliga con linters, compiladores, etc. Nos obliga a mantener siempre esta suposición para que alguien que esté usando un componente no tenga que mirar dentro del componente, porque pueden asumir con seguridad que cualquier propiedad que cambien el componente se actualizará en consecuencia y seguirá funcionando.
Esto lleva en el mundo de React a un código más robusto que tienes que actualizar menos, porque en Solid cuando escribes un hook comienzas con solo un argumento siendo una signal y luego tarde o temprano te das cuenta de que un segundo argumento también necesita cambiar en algún otro caso de uso. Comienzas a refactorizar el código, ajustando que todos los argumentos sean signals, luego tienes que refactorizar todos los casos de uso antiguos y los lugares de llamada antiguos. Esto luego lleva a este lío de tener que pensar y realmente tener que decidir explícitamente qué argumentos pueden ser signals y qué argumentos deberían ser solo valores simples. En el mundo de React todo es un valor simple y todo puede cambiar. Sí, la desventaja es que dentro de nuestros custom hooks, dentro de nuestros componentes ahora mismo tenemos que especificar manualmente las dependencias, el linter nos grita, tenemos que memorizar siempre las funciones por ejemplo para que no pierdan identidad y no cambien. Sin embargo, con algo como el próximo compilador esto puede mejorar en el futuro.
Para resumir, React nos obliga a asumir que todo puede cambiar en nuestra aplicación y a su vez podemos trabajar con valores simples, podemos tomar cualquier valor arbitrario, un número, un tipo de datos, un objeto, un objeto simple, lo que sea y podemos pasarlos y todo seguirá funcionando siempre que tengamos estos valores simples y sigamos las suposiciones de React. Si ahora todavía quieres tener signals en React o si tienes problemas de rendimiento en tu aplicación y esperas que las signals puedan resolver esos o si simplemente estás interesado en experiencias del mundo real de un proyecto basado en signals del mundo real entonces ¡hablemos! Contáctame a través de Twitter, por correo electrónico o en Discord. También estoy disponible allí y espero que hayas aprendido algo hoy y tengas algunas preguntas interesantes para mí. ¡Diviértete en la conferencia y hablamos más tarde!
Comments