Implementación de Signals en Librería Reactiva Solid

Clase 8 de 27Curso de SolidJS

Contenido del curso

Resumen

Construir un sistema reactivo propio es una de las formas más efectivas de comprender cómo funcionan internamente librerías como Solid.js. Los signals son la pieza fundamental de ese sistema, ya que interactúan con todas las demás primitivas reactivas como los effects y los memos. Aquí se explica paso a paso cómo programar esta primitiva, desde la definición de su sintaxis hasta su implementación funcional.

¿Qué es un signal y por qué es la primitiva más importante?

Un signal es un paquete que contiene un valor, y ese valor puede ser leído o escrito en cualquier momento [0:06]. Lo que lo hace tan relevante es que no trabaja de forma aislada: se conecta con el resto de las primitivas reactivas del sistema. Cada effect o memo que se construya más adelante dependerá directamente de los signals para funcionar.

Antes de escribir cualquier línea de código, es fundamental definir la sintaxis que se entregará a los usuarios de la librería [0:28]. En este caso, se sigue exactamente la convención de Solid.js.

¿Cómo se define la sintaxis de lectura y escritura?

La convención adoptada se basa en la segregación de lectura y escritura. Al invocar createSignal, se obtiene un array con dos elementos [1:06]:

  • Una función de lectura que retorna el valor actual del signal.
  • Una función de escritura (setter) que permite modificar ese valor.

En la práctica, esto luce así:

javascript const [count, setCount] = createSignal(0);

El valor 0 es el valor por defecto, pero también representa el valor que el signal mantendrá durante toda su existencia [1:30]. Cada vez que se invoque count(), se ejecuta la función de lectura. Cada vez que se llame a setCount(nuevoValor), se ejecuta la función de escritura.

¿Cómo se conecta un signal con el DOM?

Para probar el signal en acción, se utiliza un botón HTML con un event listener [0:52]. Al hacer clic, se lee el valor actual del signal y se escribe uno nuevo:

javascript document.querySelector('button').addEventListener('click', () => { setCount(count() + 1); });

Esta línea combina ambas operaciones: lectura con count() y escritura con setCount().

¿Cómo se implementa createSignal paso a paso?

La implementación vive dentro de un archivo (solid.js) que se importa como módulo [1:52]. La función createSignal recibe un parámetro value y retorna el array con las dos funciones.

javascript export function createSignal(value) { const read = () => { console.log('Leyendo signal:', value); return value; };

const write = (newValue) => { value = newValue; console.log('Escribiendo signal:', value); };

return [read, write]; }

Aquí ocurre algo poderoso gracias al dinamismo de JavaScript y los closures [3:10]. La variable value declarada como parámetro de la función se mantiene accesible tanto para read como para write. Cuando write modifica value, la siguiente invocación de read reflejará ese cambio.

¿Qué es la sintaxis ergonómica del setter?

Solid ofrece una segunda forma de escribir en un signal, más ergonómica [4:18]. En lugar de pasar un valor plano al setter, se le pasa una función que recibe como primer parámetro el valor actual del signal:

javascript setCount(prev => prev + 1);

Con esta sintaxis no es necesario conocer el nombre de la función de lectura del signal. El setter ya conoce internamente cuál es el valor actual y lo expone como argumento [4:38]. Esto resulta especialmente útil en escenarios donde se trabaja con múltiples signals y se busca claridad en el código.

Implementar esta variante dentro de la función write es un reto propuesto: detectar si newValue es una función y, de ser así, invocarla pasándole el value actual antes de asignarlo.

¿Qué sigue después de los signals?

Con la primitiva de signal funcionando, el siguiente paso es construir los effects [5:30], la segunda primitiva reactiva del sistema. Los effects se suscriben a los cambios de uno o más signals y ejecutan lógica cada vez que esos valores se modifican. Así es como el sistema reactivo cobra vida completa.

¿Ya implementaste la sintaxis ergonómica del setter? Comparte tu solución y cómo resolviste la detección entre un valor plano y una función.

      Implementación de Signals en Librería Reactiva Solid