HTMLにリアクティブな状態管理があったら? — @wcstack/state 入門
ちょっと想像してみてください。
Reactを使わず、Vueも使わず、ビルドツールも設定ファイルも何もなく、HTMLファイルひとつで「値が変わったらDOMが自動で更新される」世界。
それが @wcstack/state のコンセプトです。HTMLにちょい足しでリアクティブ機能が付いてくるお手軽ライブラリ、CDN一発で始められます。
CDN一行で始まる
<script type="module" src="https://esm.run/@wcstack/state/auto"></script>
これだけです。npm install も vite.config.js も不要。HTMLファイルをテキストエディタで書いて、ブラウザで開けばそのまま動きます。
基本の形
状態は <wcs-state> タグの中に書きます。
<wcs-state>
<script type="module">
export default {
count: 0,
increment() { this.count += 1; }
};
</script>
</wcs-state>
<p data-wcs="textContent: count"></p>
<button data-wcs="onclick: increment">+1</button>
data-wcs 属性でDOMと状態を繋ぐ。count が変わればテキストが自動で更新される。それだけです。
value にバインドすれば入力欄との双方向も自動で有効になります。{{ name }}のようにテキストを埋め込むこともできます。
<input data-wcs="value: name">
<p>こんにちは、{{ name }}さん!</p>
ルールはひとつ
状態をリアクティブに更新するルールは一つだけです。パスに直接代入する。
this.count = 10; // ✅ DOMが更新される
this["user.name"] = "Bob"; // ✅ DOMが更新される
this.user.name = "Bob"; // ❌ 検知されない
this.user.name のように書くと、Proxyが変更を捕捉できません。ドット区切りのパス文字列で代入することが、このライブラリの唯一のルールです。
配列の更新も同様で、push や splice は使えません。代わりに非破壊メソッドで新しい配列をパスに代入します。
// ✅
this.items = this.items.concat({ text: "新しいアイテム" });
this.items = this.items.toSpliced(index, 1);
// ❌
this.items.push({ text: "新しいアイテム" });
リストの表示とワイルドカード
リストの繰り返しは <template> タグで書きます。
<template data-wcs="for: users">
<div data-wcs="textContent: users.*.name"></div>
</template>
users.*.name の * が「現在の要素」を指します。ループが回るたびに * が自動的に正しいインデックスに解決されるため、手動でインデックスを管理する必要はありません。
ループの中では .name という省略記法も使えます。
<template data-wcs="for: users">
<div data-wcs="textContent: .name"></div> <!-- users.*.name と同じ -->
</template>
条件分岐
if / elseif / else も <template> で書けます。
<template data-wcs="if: count|gt(0)">
<p>カウントは正の値です。</p>
</template>
<template data-wcs="else:">
<p>ゼロ以下です。</p>
</template>
|gt(0) はフィルタで、「0より大きいか」を判定します。条件が偽のとき、要素はDOMから物理的に取り除かれます(display: none ではありません)。フィルタは組み込みで40種類用意されています。
他のライブラリとの違い
Alpine.jsのように既存のDOM要素に状態を埋め込むアプローチとは異なり、<wcs-state> は状態を独立したタグとして分離します。状態とUIの結合点はパス文字列だけで、両者はお互いの実装を知りません。
ReactやVueのような仮想DOMも持ちません。ES Proxyによってパス単位で変更を検知し、影響する要素だけを直接更新します。
シンプルなHTMLページや、フレームワークなしで動かしたい場面にフィットするライブラリです。
まとめ
| 特徴 | 内容 |
|---|---|
| インストール | CDN一行のみ |
| 状態の置き場所 |
<wcs-state> タグ |
| DOM連携 |
data-wcs 属性 |
| 更新ルール | パス代入のみ |
| ループ | <template data-wcs="for: ..."> |
| 条件分岐 | <template data-wcs="if: ..."> |
| 依存 | ゼロ |
ビルドレスでリアクティブなUIが書きたい方は、ぜひ試してみてください。