Svelte 5 → React
Svelte 5 conserva la sintaxis legacy de componentes existentes y también ofrece runes, una sintaxis del compilador para declarar reactividad. Las runes se escriben como llamadas con $ y no se importan. Puedes leer código de ambos estilos; no hace falta convertir un componente antiguo para entenderlo.
| Svelte 5 con runes | React |
|---|---|
let count = $state(0) |
const [count, setCount] = useState(0) |
let doubled = $derived(count * 2) |
const doubled = count * 2 durante el render |
onclick={increment} |
onClick={increment} |
let { user } = $props() |
function Row({ user }) |
{#if busy}…{/if} |
{busy ? <Spinner /> : <Content />} |
{#each rows as row} |
{rows.map(row => <Row key={row.id} />)} |
{@render children?.()} |
{children} |
En el modo legacy, que sigue admitido en Svelte 5, también encontrarás let count = 0, $: doubled = count * 2, export let user y <slot />. onMount(load) sigue disponible; se parece a un efecto de montaje de React, pero el ciclo de vida y el momento de ejecución no son idénticos.
Estado y valores derivados en Svelte 5
<script>
let count = $state(0);
let doubled = $derived(count * 2);
function increment() {
count += 1;
}
</script>
<button onclick={increment}>
{count} × 2 = {doubled}
</button>
Con $state, la variable sigue pareciendo una variable normal; al reasignarla la vista se actualiza. $derived expresa un valor calculado a partir de estado y props, parecido a calcular una constante durante el render de React.
Usa $effect para sincronizar con algo externo, como una API imperativa o una suscripción; no para guardar un valor que puede calcularse con $derived. $effect corre en el cliente después de actualizar el DOM y no durante el render del servidor, así que no es un reemplazo exacto de cada useEffect.
<script>
let count = $state(0);
$effect(() => {
document.title = `Clicks: ${count}`;
});
</script>
Un cálculo sencillo suele ir directamente en el componente. useMemo es para cálculos costosos o cuando se necesita conservar la identidad de un valor.
Estado
const [count, setCount] = useState(0);
function increment() {
setCount(previous => previous + 1);
}
setItems(previous => [...previous, newItem]);
Usa el setter para cambiar el estado. No mutes objetos o arrays que React ya tiene; crea un valor nuevo. Llama a los hooks en el nivel superior del componente.
Efectos y carga de datos
Un efecto sincroniza con un sistema externo al render, como una suscripción o una API. No es necesario para calcular datos derivados de props o estado.
useEffect(() => {
const controller = new AbortController();
fetch('/api/users', { signal: controller.signal })
.then(response => {
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
})
.then(setUsers)
.catch(setError);
return () => controller.abort();
}, []);
En un proyecto existente, usa el cliente de datos adoptado por el equipo; puede gestionar caché, cancelación y errores.
Props, eventos y listas
function UserRow({ user, onSelect }) {
return (
<button onClick={() => onSelect(user.id)}>
{user.name}
</button>
);
}
Los props bajan al componente hijo; los callbacks suben una intención al padre. En JSX se usa className y onClick. Cada elemento de una lista necesita una key estable, normalmente su id.
Cuando la pantalla no se actualiza
- Revisa que llamas al setter y no mutas el estado.
- Mira la consola y la pestaña Network del navegador.
- Confirma ruta base, respuesta HTTP y formato JSON.
- Identifica el setup en
package.json: Vite, Next.js u otra herramienta pueden cambiar arranque y routing.
Recursos oficiales
- Runes en Svelte 5
- Referencia de
$statey$derived - Guía de migración a Svelte 5: compatibilidad y cambios de eventos.