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
複雑なフォームの jotai 設計 / Designing jotai(state) for ...
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
izumin5210
April 23, 2025
Programming
4.7k
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
in-process GraphQL のすすめ #ginzajs
izumin5210
4
1.4k
開発体験を左右するライブラリの API 設計 - GraphQL スキーマ構築ライブラリから考える #tskaigi
izumin5210
2
2k
izumin5210のプロポーザルのネタ探し #tskaigi_msup
izumin5210
2
1k
AI Agent の開発と運用を支える Durable Execution #AgentsInProd
izumin5210
8
3k
AI Agent Tool のためのバックエンドアーキテクチャを考える #encraft
izumin5210
6
2.3k
Building AI Agents with TypeScript #TSKaigiHokuriku
izumin5210
6
1.8k
Web エンジニアが JavaScript で AI Agent を作る / JSConf JP 2025 sponsor session
izumin5210
4
3.5k
AI Coding Meetup #3 - 導入セッション / ai-coding-meetup-3
izumin5210
0
3.8k
Web フロントエンドエンジニアに開かれる AI Agent プロダクト開発 - Vercel AI SDK を観察して AI Agent と仲良くなろう! #FEC余熱NIGHT
izumin5210
3
1.3k
Other Decks in Programming
See All in Programming
仕様駆動開発へのトライを機に チームに適合する手法を模索し続けている話
freee
PRO
0
590
MySQLとPostgreSQLって何が違うの?
akagami
0
120
使いながら育てる Claude Code — 開発フローの1コマンド化 × 繰り返し指摘の自動仕組み化
shiki_kakaku
0
1.9k
Webエンジニアなのにブラウザの仕組みがわからないので、Pythonで自作してみた
tatsuki12
4
940
生成AIで帳票OCRが「簡単に」作れる時代になった?
kon_shou
0
1.1k
AI時代に設計が 最大の生産性レバーになる 意図駆動開発とデータを消さない設計|Don't Delete Your Data or Your Intent — Design as the Deepest Lever in the AI Era
tomohisa
1
1.1k
テーブルをDELETEした
yuzneri
0
150
プロポーザルを書いてもらう
pvcresin
0
570
FastAPI の並行処理モデルを完全に理解する
hoto17296
6
2.3k
<title><a id="</title>君はこのHTMLをパースできるか"></a></title> #雑LT_study
pizzacat83
0
170
jsmini JavaScript Engine を作ってみた話
yosuke_furukawa
PRO
0
350
源内ハンズオン概要編
hideg
0
200
Featured
See All Featured
Testing 201, or: Great Expectations
jmmastey
46
8.2k
Claude Code のすすめ
schroneko
67
230k
Deep Space Network (abreviated)
tonyrice
0
260
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
35
2.8k
30 Presentation Tips
portentint
PRO
1
370
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
660
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
210
Making Projects Easy
brettharned
120
6.7k
Technical Leadership for Architectural Decision Making
baasie
3
520
A Modern Web Designer's Workflow
chriscoyier
698
190k
The browser strikes back
jonoalderson
0
1.5k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.7k
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