Mejores Prácticas para Trabajar con SolidJS
SolidJS ofrece un rendimiento DOM cercano al nativo mediante reactividad de grano fino, pero ese mismo modelo introduce patrones que confunden a desarrolladores provenientes de React o Vue. Este artículo cubre las mejores prácticas de SolidJS que más importan en aplicaciones reales — aquellas que previenen errores sutiles y mantienen tu código predecible.
Puntos Clave
- Los componentes de SolidJS se ejecutan una vez como funciones de configuración — la reactividad vive a nivel de señal, no a nivel de componente
- Mantén las lecturas de señales dentro de ámbitos reactivos: expresiones JSX,
createEffect, ocreateMemo - Deriva valores con funciones o
createMemoen lugar de sincronizar estado mediante efectos - Nunca desestructures props — usa
mergePropsysplitPropspara preservar la cadena de getters - Usa
createStorepara estado anidado ycreateResourcepara obtención de datos asíncronos
Comprende que los Componentes se Ejecutan Una Vez
Este es el cambio de modelo mental del que todo lo demás depende. En React, los componentes se re-renderizan cuando el estado cambia. En SolidJS, los componentes se ejecutan una vez como funciones de configuración. La reactividad ocurre a nivel de señal, no a nivel de componente.
Esto significa que lo siguiente está roto:
function Counter() {
const [count, setCount] = createSignal(0)
const doubled = count() * 2 // Se ejecuta una vez. Nunca se actualiza.
return <div>{doubled}</div>
}
La solución es mantener las lecturas de señales dentro de ámbitos reactivos — expresiones JSX, createEffect, o createMemo:
function Counter() {
const [count, setCount] = createSignal(0)
const doubled = createMemo(() => count() * 2) // Rastrea count reactivamente
return <div>{doubled()}</div>
}
Patrones de Reactividad en SolidJS: Señales, Memos y Efectos
La reactividad de grano fino en SolidJS se construye sobre tres primitivas. Saber cuándo usar cada una es fundamental para escribir componentes SolidJS eficientes.
createSignal— para valores primitivos y estado simplecreateMemo— para valores derivados que dependen de señalescreateEffect— solo para efectos secundarios (manipulación del DOM, bibliotecas de terceros)
El error más común es usar createEffect para sincronizar estado:
// ❌ Anti-patrón: efecto usado para derivación
createEffect(() => setFullName(`${firstName()} ${lastName()}`))
// ✅ Correcto: derivar directamente
const fullName = () => `${firstName()} ${lastName()}`
Una función simple como fullName funciona porque SolidJS la re-evalúa cada vez que aparece dentro de un ámbito reactivo que lee sus señales subyacentes. Recurre a createMemo solo cuando la derivación sea costosa y quieras cachear el resultado.
Reserva createEffect para trabajo fuera del grafo reactivo de Solid — cosas como inicializar una biblioteca de gráficos o actualizar imperativamente un elemento del DOM. Consulta la explicación oficial de memos y valores derivados para más detalles.
Nunca Desestructures Props
Los props de SolidJS están respaldados por getters. Desestructurarlos rompe la conexión reactiva:
// ❌ Rompe la reactividad
function User({ name }: { name: string }) {
return <h1>{name}</h1>
}
// ✅ Preserva la reactividad
function User(props: { name: string }) {
return <h1>{props.name}</h1>
}
Cuando necesites valores por defecto o quieras separar props que consumes de props que reenvías, usa mergeProps y splitProps — ambos preservan la cadena de getters.
Discover how at OpenReplay.com.
Usa Componentes de Flujo de Control para Renderizado Condicional y de Listas
Los patrones de rendimiento de SolidJS dependen de usar las primitivas de renderizado correctas. Prefiere los componentes de flujo de control de Solid para condicionales reactivos y listas en lugar de depender de lógica JavaScript pura dentro de JSX.
// ✅ Renderizado condicional
<Show when={isLoggedIn()} fallback={<LoginPage />}>
<Dashboard />
</Show>
// ✅ Renderizado de listas — preserva la identidad de elementos entre actualizaciones
<For each={posts()}>{(post) => <PostCard post={post} />}</For>
Usa <Index> en lugar de <For> cuando las posiciones de la lista permanezcan estables pero los valores en esas posiciones puedan cambiar. <For> rastrea elementos por referencia y funciona mejor para arrays de objetos con identidad estable, mientras que <Index> rastrea elementos por posición.
Puedes leer más sobre las primitivas de renderizado de listas de Solid en la documentación oficial.
Usa Stores para Estado Complejo
Las señales rastrean cambios a un solo valor. Cuando ese valor es un objeto anidado grande, las actualizaciones reemplazan el valor completo, lo que significa que todos los consumidores de esa señal reaccionan al cambio. createStore proporciona reactividad a nivel de propiedad que funciona mejor para estado anidado:
const [state, setState] = createStore({ user: { name: "Alice" }, posts: [] })
// Solo los componentes que leen state.posts reaccionan a esto
setState("posts", (p) => [...p, newPost])
Usa produce para mutaciones complejas y reconcile cuando fusiones datos del servidor en un store existente.
Manejo Correcto de Datos Asíncronos
Obtener datos dentro de createEffect puede llevar a condiciones de carrera y no se integra limpiamente con Suspense. Usa createResource en su lugar:
const [posts] = createResource(() => fetch("/api/posts").then((r) => r.json()))
createResource acepta una señal fuente opcional como primer argumento. Cuando se proporciona, el fetcher se re-ejecuta cada vez que esa fuente cambia, y el recurso se integra automáticamente con los componentes <Suspense> y <ErrorBoundary> de Solid.
En aplicaciones SolidStart, usa query y createAsync junto con funciones de precarga. Las funciones de precarga pueden ejecutarse durante la intención de navegación (como hover sobre un enlace) y nuevamente durante la navegación, permitiendo que los datos estén listos para cuando el componente se renderice.
Conclusión
SolidJS recompensa a los desarrolladores que trabajan con su modelo de reactividad en lugar de contra él. Mantén las lecturas de señales dentro de ámbitos reactivos, deriva valores en lugar de sincronizarlos con efectos, nunca desestructures props, y recurre a createStore cuando el estado tenga estructura anidada. Estos patrones de reactividad de SolidJS no son reglas arbitrarias — son la consecuencia directa de cómo funciona la reactividad de grano fino, y seguirlos produce componentes que son tanto correctos como rápidos.
Preguntas Frecuentes
Los componentes de SolidJS se ejecutan una vez, por lo que cualquier lectura de señal asignada a una variable simple fuera de un ámbito reactivo captura solo el valor inicial. Envuelve la derivación en createMemo o coloca la lectura de señal directamente dentro de JSX. Ambos son ámbitos reactivos que se re-evalúan cada vez que la señal subyacente cambia.
Una función derivada simple funciona bien para cálculos ligeros porque SolidJS la re-evalúa cada vez que se ejecuta un ámbito reactivo consumidor. Usa createMemo cuando la derivación sea costosa o sea leída por múltiples consumidores. createMemo cachea el resultado y solo recalcula cuando sus dependencias cambian.
For rastrea cada elemento por referencia, por lo que es ideal para arrays de objetos con identidad estable. Index rastrea elementos por su posición en el array, haciéndolo más adecuado para listas donde la posición permanece estable pero el valor en esa posición puede cambiar.
Puedes, pero no deberías. Usar createEffect para sincronizar estado derivado crea actualizaciones intermedias innecesarias y puede introducir inconsistencias. En su lugar, deriva el valor con una función o createMemo. Reserva createEffect para verdaderos efectos secundarios como manipulación del DOM, logging, o interacción con bibliotecas de terceros.
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.