React使いが語るSvelteなら〇〇が要らない
File ID: 20241206214713.mdx
まとめ
- clsxが要らない
- hoge.module.cssが要らない
- Framer Motionが要らない
- setHogeが要らない
- 状態管理ライブラリが要らない
- 依存配列が要らない
- pathpidaが要らない
- Tanstack Query(SWR)が要らない
clsxが要らない
<!-- These are equivalent --><div class={isCool ? "cool" : ""}>...</div><div class:cool={isCool}>...</div>
<!-- These are equivalent --><div style:color="red">...</div><div style="color: red">...</div>
hoge.module.cssが要らない
<style>.bouncy { animation: bounce 10s;}
/* these keyframes are only accessible inside this component */@keyframes bounce { /* ... */}</style>
しかも未使用のCSSを
静的解析で検出できる!
CSS変数の扱いに長けている
<Slider bind:value min={0} max={100} --track-color="black" --thumb-color="rgb({r} {g} {b})"/>
<svelte-css-wrapper style="display: contents; --track-color: black; --thumb-color: rgb({ r } { g } { b })"> <Slider bind:value min={0} max={100} /></svelte-css-wrapper>
※ SliderコンポーネントのPropsに
渡すわけではない
もし構造を維持したいなら (標準タグが使える場合)
<input bind:value type="range" min={0} max={100} style:--track-color="black" style:--thumb-color="rgb({r} {g} {b})"/>
Framer Motionが要らない
表示非表示
<script>import { fade } from "svelte/transition";
let visible = $state(false);</script>
<button onclick={() => visible = !visible}>toggle</button>
{#if visible} <div transition:fade>fades in and out</div>{/if}
リストのアニメーション
<!-- When `list` is reordered the animation will run -->{#each list as item, index (item)} <li animate:flip>{item}</li>{/each}
setHogeが要らない
<script>let count = $state(0);</script>
<button onclick={() => count++}> clicks: {count}</button>
いわゆるSignal的な実装
状態管理ライブラリが要らない
export const myGlobalState = $state({ user: { /* ... */ }, /* ... */});
<script>import { myGlobalState } from "./state.svelte";// ...</script>;
Signalはどこでも定義可能
自然とJotaiっぽくなる
依存配列が要らない
$derived(useMemo)
<script>let numbers = $state([1, 2, 3]);let total = $derived.by(() => { let total = 0; for (const n of numbers) { total += n; } return total;});</script>
<button onclick={() => numbers.push(numbers.length + 1)}> {numbers.join(" + ")} = {total}</button>
$effect(useEffect)
<script>let size = $state(50);let color = $state("#ff3e00");
let canvas;
$effect(() => { const context = canvas.getContext("2d"); context.clearRect(0, 0, canvas.width, canvas.height);
// this will re-run whenever `color` or `size` change context.fillStyle = color; context.fillRect(0, 0, size, size);});</script>
<canvas bind:this={canvas} width="100" height="100" />
依存に含めたくない場合は
untrack
関数を使います
pathpidaが要らない
要検証(まだ自分も把握しきれてない)
<script lang="ts">import type { PageData } from "./$types";
let { data }: { data: PageData } = $props();</script>
https://svelte.dev/docs/kit/types
Tanstack Query(SWR)が 要らない
{#await promise} <!-- promise is pending --> <p>waiting for the promise to resolve...</p>{:then value} <!-- promise was fulfilled or not a Promise --> <p>The value is {value}</p>{:catch error} <!-- promise was rejected --> <p>Something went wrong: {error.message}</p>{/await}
revalidateなどが不要ならこれで十分
更新もシンプルなものなら
Promiseに再代入するだけでOK
仮想DOMが要らない
真なるリアクティブ
最後に
- SvelteはWeb開発に必要なものが最低限揃っている
- Reactでよく使うユーティリティが標準実装
- シンプルなLPなら追加の依存なしで作れそう
- Svelte v5のRuneはReactに近い書き心地
- 今までHookのような定義は少し癖があった
- あらゆるフレームワークのいいとこどり
- 学習コストはそんな高くない(ライフサイクルも素直)
- Svelte kitはまだあまり触れていないが、
仕組み自体はかなりシンプル