Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
複雑なフォームの jotai 設計 / Designing jotai(state) for ...
Search
izumin5210
April 23, 2025
Programming
4.8k
10
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
複雑なフォームの jotai 設計 / Designing jotai(state) for Complex Forms #layerx_frontend
https://layerx.connpass.com/event/348773/
izumin5210
April 23, 2025
More Decks by izumin5210
See All by izumin5210
コンパウンドプロダクト開発のためのローカルプロセスマネージャー再発明 #layerxgo
izumin5210
0
680
in-process GraphQL のすすめ #ginzajs
izumin5210
4
1.5k
開発体験を左右するライブラリの API 設計 - GraphQL スキーマ構築ライブラリから考える #tskaigi
izumin5210
2
2.1k
izumin5210のプロポーザルのネタ探し #tskaigi_msup
izumin5210
2
1.1k
AI Agent の開発と運用を支える Durable Execution #AgentsInProd
izumin5210
8
3.1k
AI Agent Tool のためのバックエンドアーキテクチャを考える #encraft
izumin5210
6
2.4k
Building AI Agents with TypeScript #TSKaigiHokuriku
izumin5210
6
1.8k
Web エンジニアが JavaScript で AI Agent を作る / JSConf JP 2025 sponsor session
izumin5210
4
3.6k
AI Coding Meetup #3 - 導入セッション / ai-coding-meetup-3
izumin5210
0
3.8k
Other Decks in Programming
See All in Programming
Webの地図
yosuke_furukawa
PRO
6
4.6k
GraphRAGのKnowledge Graphを 直接!見る/View-GraphRAG's-KnowledgeGraph-directly!
tyumugi1113
1
330
thread_parallel_with_free-threaded_Python_and_NumPy.pdf
riku_sakamoto
0
340
iOSDC Japan 2026 - Swiftで作って学ぼう!データベース自作入門
kaseken
2
170
AI × TiDD / 2026.09.05 Redmine 大阪
tokudiro
1
170
AI Agent時代のリアーキテクチャ戦略と実践
hokaccha
9
4.7k
TiDB Cloudのカスタムコントローラーによるオートスケール対応
takaidohigasi
0
120
仕様駆動開発による爆速プロダクト開発 / Bakusoku Spec Driven Development
kobakei
0
120
C#の現在地 進化の歴史と、AI時代の.NET Everywhere
neuecc
4
2.1k
App Storeの外へ──日本のiOSサイドローディング入門 for iOSDC Japan 2026
yuukiw00w
0
220
Intent as Code
shoppingjaws
6
1k
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
140
Featured
See All Featured
Test your architecture with Archunit
thirion
2
2.4k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
430
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
450
Into the Great Unknown - MozCon
thekraken
41
2.7k
Site-Speed That Sticks
csswizardry
13
1.5k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.3k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
500
We Have a Design System, Now What?
morganepeng
55
8.3k
New Earth Scene 8
popppiees
4
2.6k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.7k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
Transcript
複雑なフォームの jotai 設計 2025-04-23 Exploring State - LayerX Web Frontend
Night @izumin5210
@izumin5210 © LayerX Inc. whoami LayerX バクラク事業部 (2022-09 -) Platform
Engineering 部 Enabling チーム Staff Software Engineer Backend と Web Frontend などを書く Wantedly, Inc. (2018-04 - 2022-08) ISUCON14 4位 「状態管理ライブラリまだいらなくね?」 って言いがち
これまでのあらすじ © LayerX Inc. https://speakerdeck.com/izumin5210/number-newt-techtalk-vol-15 3
これまでのあらすじ © LayerX Inc. https://speakerdeck.com/izumin5210/number-newt-techtalk-vol-15?slide=24 4
これまでのあらすじ © LayerX Inc. https://speakerdeck.com/izumin5210/number-newt-techtalk-vol-15?slide=28 5
jotai/状態の設計について、具体例とともに深ぼっていきます © LayerX Inc. 6
例. 外貨対応の金額入力 React Hook Form + Zod の実装例 © LayerX
Inc. 通貨指定して金額入力できる 日本円換算の金額で設定された 上限バリデーションがある 7
jotai 設計: なるべく状態ではなく値に jotai での実装例 © LayerX Inc. 例. 外貨対応の金額入力
amountJpy は状態(State)ではなく、 他の値・状態から決まる値(Derived Value) 状態(State)は減らしたい 状態は書き込み可能 変な値が書き込まないような書き込みロジックが必要 考えないといけないことが増える! 8
jotai 設計: バリデーション対象は直接の 入力値に限らない © LayerX Inc. 例. 外貨対応の金額入力 ユーザが直接入力した値でなくとも、
ユーザ入力から間接的に決まるものであれば 対象になりうる React Hook Form + Zod だと watch + setValue で つらいことになりがち jotai ならキレイに書ける 9
jotai 設計: バリデーション対象は直接の入力値に限らない © LayerX Inc. 例. 外貨対応の金額入力 バリデーション対象であるということは、ドメイン上に概念・名前がある(たぶん) ドメイン上に概念・名前があるなら、コード上でも同じ概念・名前をつけよう
バリデーションに埋まったドメインロジックを自然に分離できるのもポジティブ 10
現実はもっと複雑 © LayerX Inc. 11
例. 外貨対応の金額入力 Lv.2 こうなってくるとテストも大変… React Hook Form での実装例(ちょっと悪意がある) © LayerX
Inc. 通貨指定して金額入力できる 日本円換算の金額で設定された 上限バリデーションがある 換算レートは外部から取得する ← New! 12
jotai 設計: Derived Atom は 非同期もそのまま扱える jotai での実装例 © LayerX
Inc. 例. 外貨対応の金額入力 Lv.2 Derived Atom は Promise を返すことができる derive() を使った async sometimes パターン で Promise<T> | T が返る React につなぐときは必要に応じて Suspend してくれる 非同期の値を書き込むための状態は不要 非同期であっても書き味は大きく変わらない 「データグラフでドメインを自然に表現できる」 という利点 が損なわれない Jotai v2を使いこなすために実は必須級な“async sometimes”パターンの解説 https://zenn.dev/uhyo/articles/jotai-v2-async-sometimes 13
現実はまだまだ複雑 © LayerX Inc. 14
例. 外貨対応の金額入力 Lv.3 © LayerX Inc. 通貨指定して金額入力できる 日本円換算の金額で設定された 上限バリデーションがある 換算レートは外部から取得する
ただし、ユーザが自分で入力することも可能 ← New! e.g. 日本円を現地通貨に両替したときの領収書からレートを決める場合 15
jotai 設計: async sometimes atom から 更に derived atom を作れる
© LayerX Inc. 例. 外貨対応の金額入力 Lv.3 [async fetchedRate, manualRate] → async rate → async amountJpy atom() が derived() に変わるが、 データの依存グラフを作って必要な値を得る… というモデルは変わらない 16
現実は… © LayerX Inc. 17
例. 外貨対応の金額入力 Lv.4 © LayerX Inc. 通貨指定して金額入力できる 日本円換算の金額で設定された 上限バリデーションがある 換算レートは外部から取得する
ただし、ユーザが自分で入力することも可能 カード決済の場合、金額とレートはカードの決済情報から決まる ← New! 18
jotai設計: ユーザが直接編集する状態 と、別の値から決まる値は分ける © LayerX Inc. 例. 外貨対応の金額入力 Lv.4 特に「変更不可能な補完入力」については、
ユーザが入力する状態と分けてあげる 「状態」の責務を減らす 「その値がどこから来たのか」を コード上・動作上いずれにおいてもトレース可能にする 19
現実… © LayerX Inc. 20
現実… まあ今日は一旦これくらいで © LayerX Inc. 21
ここまでのまとめ 現実っぽい例をもとに、jotai の設計プラクティスをいくつか紹介した © LayerX Inc. なるべく状態ではなく値に バリデーション対象は直接の入力値に限らない バリデーションのために設計を歪めない ユーザが直接編集する状態と、別の値から決まる値は分ける
状態の責務を減らし、その値の由来をトレースしやすくしておく Derived Atom は非同期もそのまま扱える async sometimes atom から更に derived atom を作れる 同期・非同期が混ざっていても、コード上は(比較的)滑らかに記述できる 22
ここまでのまとめ… からの学び 結局なにが言いたいか © LayerX Inc. なるべく状態(State)ではなく値(Derived Value)に 状態(State)を減らす ユーザが直接編集する状態と、別の値から決まる値は分ける
状態(State)の責務を減らす Derived Atom は非同期もそのまま扱える 非同期処理からの書き込みを回避でき、結果として状態(State)が減る 23
「状態」はむずかしい! © LayerX Inc. 「状態」を「読み書き可能な値」ととらえると、「書き込み」の制御が必要になる 「書き込む」という処理を適切に呼び出させないといけない 「状態」の利用者側に「考える」 「適切に使う」という仕事を押し付けている (この 利用者
は AI であることも多くなる… どうやって徹底させるか) なので、「状態」は減らしたい なるべく Derived Value にする jotai であれば、非同期処理が混ざっても、わりと自然に Derived Value として記述できる なくせない「状態」であっても、責務を減らすことで利用者の負担を減らせる 今回の例だと「ユーザが直接編集する状態と、別の値から決まる値は分ける」ことで 状態ごとのユースケースを絞り、利用者の考えることを減らす 24
我々は「状態」を減らすために jotai を使っているのかもしれない… © LayerX Inc. 25