Condicionales y early return
Por qué un if en el cuerpo del componente rompe la reactividad, y por qué en Solid se ramifica con Show y Switch dentro del JSX, no con control de flujo imperativo ejecutado una sola vez.
Un if en el cuerpo se evalúa una vez
function Roto(props) { // el cuerpo corre UNA vez: este if usa el valor inicial y ya if (props.cargando) { return <Spinner />; // si arranca cargando, se queda en Spinner PARA SIEMPRE } return <Datos valor={props.datos} />;}props.cargando se lee una sola vez, cuando corre el cuerpo. Si era true al crearse, el componente devuelve <Spinner /> y no vuelve a evaluarse jamás; cuando cargando pase a false, nada re-ejecuta el cuerpo, así que el spinner se queda clavado. El return cortocircuitó el grafo: eligió una rama en el instante del montaje y la fijó. El if no es reactivo porque el cuerpo no es reactivo.
Ramificar dentro del JSX: Show
Show reevalúa su prop when de forma reactiva porque vive en el JSX, que el compilador rastrea:
import { Show } from "solid-js";function Bien(props) { return ( <Show when={!props.cargando} fallback={<Spinner />}> <Datos valor={props.datos} /> </Show> );}when es una expresión que el compilador envuelve en un efecto; cuando props.cargando cambia, Show intercambia entre sus hijos y el fallback. Por defecto, Show no recrea los hijos mientras la verdad de when no cambie de valor booleano. Con keyed fuerza la recreación cuando cambia la identidad del valor y te lo pasa, ya estrechado, como argumento de una función:
<Show when={usuario()} keyed fallback={<p>anonimo</p>}> {(u) => <Perfil id={u.id} />}</Show>Varias ramas: Switch, Match y Dynamic
Para más de dos ramas, Switch con Match en lugar de cadenas de else if. Solo se monta el primer Match cuyo when sea verdadero, y todo reacciona:
import { Switch, Match } from "solid-js";<Switch fallback={<p>desconocido</p>}> <Match when={estado() === "cargando"}><Spinner /></Match> <Match when={estado() === "error"}><ErrorVista /></Match> <Match when={estado() === "listo"}><Datos /></Match></Switch>Cuando lo que cambia es qué componente montar, Dynamic despacha por valor sin escribir tú el condicional:
import { Dynamic } from "solid-js/web";const registro = { alfa: Alfa, beta: Beta };<Dynamic component={registro[tipo()]} etiqueta="hola" />Conviene notar que los hijos de Show pueden ser una función, no solo elementos. La forma de función se evalúa de manera perezosa y evita construir el subárbol hasta que la condición se cumple, lo que ahorra trabajo cuando el contenido es caro.
// el contenido caro no se crea mientras when sea falso<Show when={abierto()}> {() => <PanelPesado datos={datos()} />}</Show>Y cuando ninguna rama aplica, Switch y Show aceptan fallback; Dynamic puede combinarse con Show para elegir componente y, a la vez, cubrir el hueco mientras se decide.
// elegir componente y cubrir el hueco a la vez<Show when={cargado()} fallback={<Spinner />}> <Dynamic component={vistas[tipo()]} /></Show>Iterar también es flujo de control
La misma lógica se extiende a las listas: recorrer una colección es otra forma de control de flujo que debe vivir en el JSX. Un .map() en el cuerpo se evaluaría una vez y quedaría congelado; por eso Solid ofrece For e Index.
import { For, Index } from "solid-js";// For: se identifica por REFERENCIA del elemento. Reordenar mueve nodos.<For each={items()}> {(item, i) => <li>{i()}: {item.texto}</li>}</For>// Index: se identifica por POSICION. El elemento es un signal.<Index each={items()}> {(item, i) => <li>{i}: {item().texto}</li>}</Index>La diferencia es profunda y es puramente reactiva: For reconcilia por identidad del elemento, así que si reordenas la lista, mueve los nodos del DOM ya creados; cada item es un valor fijo y el índice i es un signal. Index reconcilia por posición: cada item es un signal y el índice es fijo. Usa For para listas de objetos que se reordenan; Index para primitivos o para campos de formulario donde la posición manda.
Los operadores nativos del JSX —el ternario y el &&— también son reactivos, porque el compilador los rastrea. Pero Show gana cuando necesitas un fallback o el modificador keyed, y Switch gana cuando hay tres o más ramas, porque evita anidar ternarios ilegibles.