Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Preact、HooksとSignalsの両立 / Preact: Harmonizing H...
Search
TOMIKAWA Sotaro
March 28, 2025
Programming
3.4k
1
Share
Preact、HooksとSignalsの両立 / Preact: Harmonizing Hooks and Signals
https://vuejs-meetup.connpass.com/event/343338/
TOMIKAWA Sotaro
March 28, 2025
More Decks by TOMIKAWA Sotaro
See All by TOMIKAWA Sotaro
Atomics APIを知る / Understanding Atomics API
ssssota
2
1.2k
なんでRustの環境構築してないのにRust製のツールが動くの? / Why Do Rust-Based Tools Run Without a Rust Environment?
ssssota
15
54k
Web技術を最大限活用してRAW画像を現像する / Developing RAW Images on the Web
ssssota
2
3k
漸進。
ssssota
0
3.5k
useSyncExternalStoreを使いまくる
ssssota
6
6.7k
React CompilerとFine Grained Reactivityと宣言的UIのこれから / The next chapter of declarative UI
ssssota
8
6k
新しいAPI createRawSnippet触ってみた / What is the createRawSnippet?
ssssota
2
300
脱法Svelte / Evasion of svelte rules
ssssota
1
320
Documentation testsの恩恵 / Documentation testing benefits
ssssota
2
1.2k
Other Decks in Programming
See All in Programming
個人的に嬉しかったpnpmの新機能・3選
matsuo_atsushi
0
110
実用!Hono RPC2026
yodaka
2
280
「Linuxサーバー構築標準教科書」を読んでみた #ツナギメオフライン.7
akase244
0
1.4k
10年分の技術的負債、完済へ ― Claude Code主導のAI駆動開発でスポーツブルを丸ごとリプレイスした話
takuya_houshima
0
2.7k
Swift Concurrency Type System
inamiy
1
560
Vibe NLP for Applied NLP
inesmontani
PRO
0
530
UIの境界線をデザインする | React Tokyo #15 メイントーク
sasagar
2
400
Kingdom of the Machine
yui_knk
2
1.2k
決定論 vs 確率論:Gemini 3 FlashとTF-IDFを組み合わせた「法規判定エンジン」の構築
shukob
0
140
「話せることがない」を乗り越える 〜日常業務から登壇テーマをつくる思考法〜
shoheimitani
4
910
【26新卒研修資料】TDD実装演習
dip_tech
PRO
0
130
ルールルルルルRubyの中身の予備知識 ── RubyKaigiの前に予習しなイカ?
ydah
1
230
Featured
See All Featured
Building a Scalable Design System with Sketch
lauravandoore
463
34k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.8k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.2k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
270
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
170
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.1k
Thoughts on Productivity
jonyablonski
76
5.1k
Fireside Chat
paigeccino
42
3.9k
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
110
Being A Developer After 40
akosma
91
590k
The Language of Interfaces
destraynor
162
26k
Transcript
Preact、 HooksとSignalsの両立 Preact: Harmonizing Hooks and Signals #v_tokyo22 / ssssota
自己紹介 ssssota { "twitter": "@ssssotaro", "github": "ssssota", "bsky": "@ssssota.bsky.social" }
株式会社ZOZO フロントエンドテックリード 仕事でReact、 趣味でSvelteやPreactを主に触っている。
Preact ? > Fast 3kB alternative to React with the
same modern API > Preact(プリアクト)はDOM上に薄い仮想DOMによる抽象化を提供します。 https://preactjs.com/ React互換を謳う軽量な仮想DOMライブラリ。 Reactの進化についていく気がないので互換性については...。 DenoがFreshに採用するなど、死んではいない。 Majorバージョンの更新こそないが、Minorバージョンの更新はある。
Hooks ? いわゆるReact Hooks。 useState, useEffect, useRef, etc… 関数コンポーネントにリアクティビティ(状態や副作用)を導入する道具。 登場当時はクラスコンポーネントが主流だった。しかしクラスインスタンス自体が状態
を持つことで、ロジックの分離が困難になっていた。 フックによりロジックは再利用性が向上。コンポーネントとはより疎な関係に。 Preactでは、Reactの一部フックが同様に利用できる。
Signals ? preact本体とは別パッケージ(@preact/signals)として提供されていつつも、 高度に統合されたSignals実装。 signal, computed, effectなど基本的なAPIから、 関数コンポーネント/カスタムフックから利用するための useSignal, useComputed,
useSignalEffectなどが提供されている。 限定的ではあるもののFine-grained Reactivityが実現されている。
options Preactにはoptionsというオブジェクトがexportされている。 このオブジェクトにはPreactが内部的に利用するライフサイクルフックが登録され、 上書きすることにより各種挙動の拡張を可能にしている。 @preact/signalsはoptionsのライフサイクルフックを上書きすることで SignalをPreactに統合している。
Reactivity with Hooks(VDOM) Code (Preact / React) function Counter() {
const [count, setCount] = useState(0); const increment = () => setCount(p => p + 1); return ( <div> {count} <button onClick={increment}>+1</button> </div> ); }
Reactivity with Hooks(VDOM) VDOM UI 0 [+1] Code function Counter()
{ const [count, setCount] = useState(0); const increment = () => setCount(p => p + 1); return ( <div> {count} <button onClick={increment}>+1</button> </div> ); }
Reactivity with Hooks(VDOM) VDOM (ボタン押下でsetCountが呼ばれる) UI 0 [+1] Code function
Counter() { const [count, setCount] = useState(0); const increment = () => setCount(p => p + 1); return ( <div> {count} <button onClick={increment}>+1</button> </div> ); }
Reactivity with Hooks(VDOM) VDOM (VDOMを作り直して比較) UI 0 [+1] Code function
Counter() { const [count, setCount] = useState(0); const increment = () => setCount(p => p + 1); return ( <div> {count} <button onClick={increment}>+1</button> </div> ); }
Reactivity with Hooks(VDOM) VDOM UI (差分を適用) 1 [+1] Code function
Counter() { const [count, setCount] = useState(0); const increment = () => setCount(p => p + 1); return ( <div> {count} <button onClick={increment}>+1</button> </div> ); }
Reactivity with Signals(VDOM) Code (Preact) function Counter() { const count
= useSignal(0); const increment = () => { count.value += 1; }; return ( <div> {count.value} <button onClick={increment}>+1</button> </div> ); }
Reactivity with Signals(VDOM) VDOM UI 0 [+1] Code function Counter()
{ const count = useSignal(0); const increment = () => { count.value += 1; }; return ( <div> {count.value} <button onClick={increment}>+1</button> </div> ); }
Reactivity with Signals(VDOM) VDOM (ボタン押下でcountがインクリメント) UI 0 [+1] Code function
Counter() { const count = useSignal(0); const increment = () => { count.value += 1; }; return ( <div> {count.value} <button onClick={increment}>+1</button> </div> ); }
Reactivity with Signals(VDOM) VDOM (VDOMを作り直して比較) UI 0 [+1] Code function
Counter() { const count = useSignal(0); const increment = () => { count.value += 1; }; return ( <div> {count.value} <button onClick={increment}>+1</button> </div> ); }
Reactivity with Signals(VDOM) VDOM UI (差分を適用) 1 [+1] Code function
Counter() { const count = useSignal(0); const increment = () => { count.value += 1; }; return ( <div> {count.value} <button onClick={increment}>+1</button> </div> ); }
Reactivity 基本方針は、「Signalが更新されたらそのコンポーネントを再レンダリング」。 あくまでも仮想DOMベースのリアクティブシステムなので、 1. 状態を元に仮想DOMの構築 2. 仮想DOMツリーを比較 (diffing / reconciliation) 3.
実DOMへの反映 (render / commit) が基本。Signalsを使っても同じ規則に従うことで共存できる。 PreactのSignalsは限定的なFine-grained Reactivityが実現されている。 仮想DOMの構築やツリーの比較を行わずにDOMを更新できるので速い。
Fine-grained Reactivity with Signals(VDOM) Code (Preact) function Counter() { const
count = useSignal(0); const increment = () => { count.value += 1; }; return ( <div> {count /* UPDATED! (before: count.value) */} <button onClick={increment}>+1</button> </div> ); }
Fine-grained Reactivity with Signals(VDOM) VDOM UI 0 [+1] Code function
Counter() { const count = useSignal(0); const increment = () => { count.value += 1; }; return ( <div> {count} <button onClick={increment}>+1</button> </div> ); }
Fine-grained Reactivity with Signals(VDOM) VDOM (ボタン押下でcountがインクリメント) UI 0 [+1] Code
function Counter() { const count = useSignal(0); const increment = () => { count.value += 1; }; return ( <div> {count} <button onClick={increment}>+1</button> </div> ); }
Fine-grained Reactivity with Signals(VDOM) VDOM (count使用箇所更新) UI (count使用箇所更新) 1 [+1]
Code function Counter() { const count = useSignal(0); const increment = () => { count.value += 1; }; return ( <div> {count} <button onClick={increment}>+1</button> </div> ); }
None
PreactのSignalは通常 .value プロパティによって値を取得・更新できる。 しかし、JSXの各値にSignalをそのまま設定できる。 その部分はFine-grained Reactivityが適用される。 <p>{someSignal /* someSignal.value ではなくていい
*/}</p> <input value={someSignal /* someSignal.value ではなくていい */} onChange={(e) => (someSignal.value = e.currentTarget.value)} /> 限定的...? Fine-grained Reactivity
Limitation of Preact signals JSX内で .value をつけなければFine-grained Reactivityを適用できるが、常 にFine-grained Reactivityが適用できるわけではない。
例えば、 1. {themeSignal.value === 'light' ? <Light /> : <Dark />} 2. {listSignal.value.map(item => <Item item={item} />)} 条件分岐と反復に関してはFine-grained Reactivityが適用できない =変化時、仮想DOMの再構築が必須 (SolidJSでも <For/> や <Switch/> などで同様の制約を回避)
const countGlobalSignal = signal(0); function Counter() { const countLocalSignal =
useSignal(0); const [count, setCount] = useState(0); return ...; } もちろん同時に使える。 とはいえ、 useSignal と useState を乱用すると治安が崩壊する。 「useSignal 禁止」など、プロジェクト毎にルールを決めてご利用は計画的に。 Hooks and Signals
まとめ PreactにはSignalsがある。 Preact本体とは別パッケージながらoptionsにより統合されている。 Signalsは分岐と反復で制約を受けるもののFine-grained Reactivityを実現、 パフォーマンスに寄与する。 PreactにはHooksもあり、共存できる。状況に応じ使い分けよう。 Signalsのパフォーマンスは良いが、PreactではHooksを圧倒するものではない。 JSXだし、Reactより軽量だし、それなりに速いし、Signalsあるし、 Preactっておもしれーライブラリ。