Slide 1

Slide 1 text

2026-09-12 フロントエンドカンファレンス福岡 2026

Slide 2

Slide 2 text

おはようございます 2

Slide 3

Slide 3 text

おはようございます 3

Slide 4

Slide 4 text

発表者紹介 uhyo 株式会社カオナビ フロントエンドエキスパート 4

Slide 5

Slide 5 text

今日はReactについてお話しします 5

Slide 6

Slide 6 text

今日はReactについてお話しします 6

Slide 7

Slide 7 text

今日は宣言的UIについてお話しします 7

Slide 8

Slide 8 text

なぜフロカン福岡でこの話をするのか あのころ、宣言的UIは未来だった。 今では、フロントエンドにおいて普遍的なもの になった。 8

Slide 9

Slide 9 text

なぜフロカン福岡でこの話をするのか Reactは、Async Reactを通じて、次の未来を 提示した。 それは、宣言的UIの進化でもあった。 9

Slide 10

Slide 10 text

This Talk Reactは宣言的UIを普及させたライブラリである。 それからUIライブラリも進化したが、 Reactは今でも宣言的UIに徹底的に向き合い続け るライブラリである。 そのことを、Reactの設計論を通じて紹介したい。 10

Slide 11

Slide 11 text

トークから持ち帰ってほしい問い Reactを使っている方: 自分たちはReactの機能を活かして、 宣言的UIの恩恵を最大限受けているのか? React以外を使っている方: このライブラリで同じレベルの宣言的UIをやるには どうすればいい? 自分はそれができているか? 11

Slide 12

Slide 12 text

トークから持ち帰ってほしい問い 例えば、Solid 2はそういったAPIを備えていそう。 12

Slide 13

Slide 13 text

Ⅰ. モダン 宣言的UI 13

Slide 14

Slide 14 text

よく知られた宣言的UIのスローガン UI = f(state) 14

Slide 15

Slide 15 text

よく知られた宣言的UIのスローガン UIを直接変化させるのではない。 変化するのは状態であり、UIは状態 から計算される。 UI = f(state) 15

Slide 16

Slide 16 text

宣言的UIの実装 Reactはこれを仮想DOMを用いて実装した。 しかし、仮想DOMを用いないライブラリもある。 Reactでは、仮想DOMは高度なスケジューリング の礎となり、良いUXを生み出す基盤となっている。 (描画の中断機構として今日の話でも活躍します) 16

Slide 17

Slide 17 text

良いUX 17

Slide 18

Slide 18 text

In the day 1 keynote, Joe Savona shared our goals and vision for React to make it easy for anyone to build great user experiences. ― React Conf 2024 Recap https://react.dev/blog/2024/05/22/react-conf-2024-recap 18

Slide 19

Slide 19 text

UIライブラリは良いUXのために UIライブラリは、ただUIを組み立てるだけが 役割ではない。 開発者が良いUXを実装するのを支援するという 役割がある。 少なくともReactはそう考えている。 19

Slide 20

Slide 20 text

最適化から良いUXがもたらされる 宣言的UIでは、開発者がUIの仕様を宣言する。 Reactランタイムは、宣言された仕様を 満たさなければならない。 言い換えれば、仕様の範囲内で最適化できる。 Reactは仕様の範囲内でなるべく良いUXを 実現しようとする。 20

Slide 21

Slide 21 text

例: React Compiler React Compilerは直球な最適化の例である。 レンダリング結果を変えない範囲で作業を 削減する。 その結果再レンダリングが高速化し、 良いUXにつながる。 21

Slide 22

Slide 22 text

正確に宣言し、より多く最適化する 具体的な動作を書くのではなく宣言的にUIを 書けば、最適化の余地がより生まれる。 求める仕様を正確に記述しよう。 不要な制約を除去し、本当に必要なものは 何なのか考えよう。 22

Slide 23

Slide 23 text

Async React 23

Slide 24

Slide 24 text

await UI = await f( await state) 24

Slide 25

Slide 25 text

await UI = await f( await state) https://www.youtube.com/watch?v=B_2E96URooA 25

Slide 26

Slide 26 text

Async React概要 Async Reactは、非同期処理をReactランタイムが 取り扱うための一連の機能であり、 それをエコシステムに普及させるための動きでも ある。 26

Slide 27

Slide 27 text

UIと非同期処理 UIは、さまざまな場面で時間がかかる。 • データ取得 = 表示できるまで時間がかかる • 更新系API = 操作の結果が出るまで時間がかかる • アニメーション = UIの遷移完了まで時間がかかる 27

Slide 28

Slide 28 text

UIと非同期処理 対応する主なReactの機能: • データ取得 = Suspense • 更新系API = useActionState • アニメーション = ViewTransition (今日は下2つは触れません) 28

Slide 29

Slide 29 text

UIと非同期処理 Async React時代では、非同期処理の取り扱いが React本体に組み込まれている。 29

Slide 30

Slide 30 text

Suspenseの例 30

Slide 31

Slide 31 text

31

Slide 32

Slide 32 text

Suspenseは何を宣言して いるのか? 32

Slide 33

Slide 33 text

Suspenseが宣言するもの UIの独立性を宣言している。 独立していない部分は、 サスペンド時に一蓮托生になる。 33

Slide 34

Slide 34 text

34

Slide 35

Slide 35 text

35

Slide 36

Slide 36 text

Suspense境界の意味付け 「これとこれは一緒に出さないとだめ」 「これとこれは別々に出してもいい」 具体的な動きではなく、制約を表現している。 36

Slide 37

Slide 37 text

Suspense境界の最適化 具体的な動作ではなく制約を指示したことで、 その範囲で自由な最適化が可能。 例: 37

Slide 38

Slide 38 text

制約、別の見方をすれば保証 38

Slide 39

Slide 39 text

Reactの2つの保証 我々は、知らないうちに2つの保証を受けている。 一貫性: 画面上で状態が混在しない 即時性: ステート更新が最優先で画面に反映される 39

Slide 40

Slide 40 text

Reactの一貫性保証 UI = f(state) が守られるという保証。 具体的には、 ステートが変化したとき、変化前と変化後のUIが 混ざって表示されないという保証。 40

Slide 41

Slide 41 text

一貫性保証の例 strが″foo″から″bar″に変わったとき、 必ず全てが変わった状態を表示する。 Reactは一部だけ変わった状態を描画しない。 41

Slide 42

Slide 42 text

一貫性保証はなぜ必要か 壊れたUI・中途半端なUIをユーザーに見せない という、基本的なUXのため。 React自体が持つ性質であり、開発者はこの性質 を仮定した上でUIを実装することができる。 42

Slide 43

Slide 43 text

Suspenseに当てはめると…… このコードでは、strが変わった瞬間に再サスペンド して、Suspenseがフォールバックに戻る。 43

Slide 44

Slide 44 text

Suspenseに当てはめると…… 44

Slide 45

Slide 45 text

それって良いUXなの? 45

Slide 46

Slide 46 text

再サスペンドの問題点 再サスペンドが一瞬の場合、ちらつく。 (古い結果→スケルトン→新しい結果という2回の書き換え) 新しい結果を待っている間、古い結果が片付け られてローディングを見せられるのは、 別に嬉しくない。(場合にもよる) 46

Slide 47

Slide 47 text

トランジション 47

Slide 48

Slide 48 text

トランジションの導入 useTransitionなど、トランジションを発生 させるAPIが存在する。 ステート更新をトランジションでラップする ことで、その更新におけるReactの挙動に影響 を与える。 48

Slide 49

Slide 49 text

トランジションにした場合 49

Slide 50

Slide 50 text

トランジションの挙動の解釈 Reactはstr=“ab”の結果を即時出さず、 古い画面を出し続けた。 これは、トランジションが即時性保証を緩和 したから。 スケルトンが出るより古い結果を出し続けたほう がUXが良いという判断である。 50

Slide 51

Slide 51 text

宣言的UIの観点でのトランジション トランジションは即時性保証の緩和を宣言する。 制限が緩和される → 最適化の余地 → 良いUX! 51

Slide 52

Slide 52 text

useTransitionの2つの効果 即時性保証の緩和を受けて、 Reactは2つのUX最適化を行う。 • 更新を優先度の低いLaneに割り当てる • 再サスペンド時のフォールバック抑止 52

Slide 53

Slide 53 text

ReactのLaneモデル 何に由来する更新かに よってタスクの優先度 が異なる。 割り込み機構を実現する モデル。 53

Slide 54

Slide 54 text

注意: トランジションは遅いとは限らない 即時性保証の緩和により反映が遅くなる可能性は ある。 しかし、割り込みやサスペンドなどの邪魔する ものが無い場合は普通に速い。 もちろん、なるべく早く反映したほうがいい場面 ではReactは早く画面に反映する。 54

Slide 55

Slide 55 text

もう1つの解決法: useDeferredValue 即時性保証を緩和するするのではなく、 一貫性保証を緩和することでもUXを最適化可能。 55

Slide 56

Slide 56 text

もう1つの解決法: useDeferredValue 56

Slide 57

Slide 57 text

useDeferredValueの挙動 57

Slide 58

Slide 58 text

useDeferredValueの挙動 一貫性の崩れ 58

Slide 59

Slide 59 text

useDeferredValueの意味 良いUXのために、一貫性保証を緩めることを宣言。 どう緩めるかをプログラムで宣言できる、 柔軟なAPIになっている。 59

Slide 60

Slide 60 text

ここまでのまとめ 60

Slide 61

Slide 61 text

Ⅱ. トランジションの活用 61

Slide 62

Slide 62 text

じゃあ、どのステート更新を トランジションにすべきなの? 62

Slide 63

Slide 63 text

答え: ほぼ全て “In a typical React app, most updates are conceptually transition updates.” ― Rick Hanlon, New feature: startTransition (React 18.0当時の発言) https://github.com/reactwg/react-18/discussions/41 63

Slide 64

Slide 64 text

こんな発言も “For example, anything that animates should ideally go into one of these.” ― Sebastian Markbåge, New feature: startTransition (React 18.0当時の発言) https://github.com/reactwg/react-18/discussions/41 この発言はViewTransitionとしてReact 19.3で結実。 64

Slide 65

Slide 65 text

緊急更新の使いどころ 即時性が求められる更新は緊急更新と呼ばれる。 世の中、本当に緊急な更新は少ない。 では、Reactではどんな更新が緊急更新なのか? 65

Slide 66

Slide 66 text

一般的なReactアプリケーションにおいては、 緊急更新は辻褄合わせの更新である 66

Slide 67

Slide 67 text

辻褄合わせの更新 すでに起こった変化にReactのステートを 合わせにいく更新のこと。 代表例: 制御コンポーネント 67

Slide 68

Slide 68 text

辻褄合わせの更新 68

Slide 69

Slide 69 text

辻褄合わせの更新(他の例) useSyncExternalStoreによる更新は、 トランジションにはならない。 外部システムですでに起こった更新を Reactの世界に反映するものだから。 69

Slide 70

Slide 70 text

それ以外 何らかのイベント(ユーザー操作など)によって 新たに画面が変化するものは、 もう全部トランジションでいい。 (非常に反応速度が大事な例外は除く) 70

Slide 71

Slide 71 text

なので…… 71

Slide 72

Slide 72 text

Reactの設計論 トランジションの存在を前提に設計する。 トランジションを介してアプリの他の箇所と 連携する。 72

Slide 73

Slide 73 text

例: action prop 73

Slide 74

Slide 74 text

action prop 74

Slide 75

Slide 75 text

ポイント: action prop 汎用ボタンコンポーネントが、onClickではなく action propを受け取る設計のこと。 (もちろん任意のコンポーネント・イベント等に応用可能) そして、ボタン内部でactionはstartTransitionに ラップされている。 75

Slide 76

Slide 76 text

ポイント: action prop 76

Slide 77

Slide 77 text

action propの利点 「処理中に表示が変わる」という要件を、 自己完結した形で実装できた。 Reactランタイムを通じて、 ボタンの責務を「自分が発生させた処理」まで 拡張できた。 77

Slide 78

Slide 78 text

isPendingの解釈 トランジションの間はisPendingがtrueになる。 日本語に訳すと「遷移」。 ボタンを押した影響で画面が遷移している最中 というフラグだと考えよう。 78

Slide 79

Slide 79 text

action propの注意① ボタンの中でisPendingを使わない場合でも、 action propにしていい。 自動でトランジション化されるだけでも価値が ある。 (actionという命名でトランジション化されることが伝わる) 79

Slide 80

Slide 80 text

action propの注意② await action()の完了=isPendingがfalseに戻る、 とは限らない。 actionによりサスペンドした場合、そのサスペン ド完了までトランジションが続く。 80

Slide 81

Slide 81 text

トランジションでもっと 良いUXを作りたい! 81

Slide 82

Slide 82 text

そんなあなたの強い味方、 useActionState 82

Slide 83

Slide 83 text

については省略します。記事読んでね 83

Slide 84

Slide 84 text

同じく強い味方、useOptimistic 84

Slide 85

Slide 85 text

useOptimisticが解決する問題 ユーザー入力に応じてトランジションが発生する 場合、すぐに画面に反映されない可能性がある。 本当の結果が画面に出るまでの繋ぎが必要。 85

Slide 86

Slide 86 text

useOptimisticの役割 もちろん、名前にあるとおり楽観的更新が役割。 しかし、実はかなりの応用力の持ち主。 トランジション中の画面表示の制御に 広く活用可能。 86

Slide 87

Slide 87 text

実はこれと同じ 87

Slide 88

Slide 88 text

実はこれと同じ isPendingをuseTransitionから取得する代わりに、 トランジション開始した瞬間にuseOptimisticで isPendingをtrueにすることも可能。 トランジション中でも即座に画面に反映したい 更新全般にuseOptimisticを活用できる。 88

Slide 89

Slide 89 text

例: カートの楽観的更新 本当にカートに入っている商品と、楽観的更新で カートに入って いる商品を区別 した形で表示で きる。 89

Slide 90

Slide 90 text

useOptimisticによる発想の転換 旧来の考え方: isPendingや楽観的更新の恩恵を受けたいから トランジションを使う。 新しい考え方: 画面の変化はトランジションが当たり前。 それベースでUX向上する手段として useOptimisticを使う。 90

Slide 91

Slide 91 text

Ⅲ. まとめ 91

Slide 92

Slide 92 text

Reactと宣言的UI Reactは宣言的UIだが、それはただ単にコンポー ネントを“純粋関数”で書くことだけではない。 Reactが提供する保証やトランジションの概念を 土台に、UI全体を宣言的に組み立てていく。 その結果、最適化という形で良いUXが得られる。 これがReactにおける宣言的UIである。 92

Slide 93

Slide 93 text

トランジションの活用 実践的には、トランジションがデフォルトという 考えを持ちたい。 トランジションにすることに目的意識は要らない。 トランジションにしないことのほうが特別。 93

Slide 94

Slide 94 text

Async Reactの普及と実践 useTransitionやuseOptimisticなどを全て手で 書くのではなく、エコシステムに組み込んでいく のがReactの考え。 社内でも、共通ライブラリや共通コンポーネント にこの考え方を適用できる。 94

Slide 95

Slide 95 text

まとめ: Reactの設計論 Reactの基礎となる概念を学ぼう。 アプリ全体を宣言的に書く意識を持とう。 全てをトランジションにしよう。 95