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
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
620
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.3k
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
初心者DevRelとして参加者だった私が、DevRel Talks!#2に登壇するまでにしてきたこと
sokohirai
0
330
いまどきの Codex で開発する visionOS アプリの開発スタイルについて
karad
0
180
AWS Transform Customによる Spring Boot 2.xから4.xへのVerUp
satoshi256kbyte
2
130
「AI時代、配布するPythonコードをどう守るか: 難読化の実験と判断軸」 #PyconJP2026
pkshadeck
PRO
2
110
週末にAI-DLCを本気で回したら$1,600溶けた
hbashimizu
0
120
typoなんかねぇよ
raspython3
0
660
AWS Step Functions 大規模並列の壁を越える / jaws-sonic-2026-niigata-step-functions
kasacchiful
PRO
0
280
Seeing Through Serverless: Observability for AWS Lambda with ADOT and CloudWatch Application Signals
seike460
PRO
1
110
Pythonの実行はどこまで賢くなったのか? CPythonとPyPyから見る最適化のしくみ
curekoshimizu
4
2.7k
LL言語やWebフレームワークのPostgreSQL対応 〜DBの機能がユーザーに届くまで〜
kentaroutakeda
0
130
楽しそうなつよつよエンジニアと目が死んでる僕/A brilliant engineer having a blast, and dead-eyed me.
3l4l5
2
280
MySQLとPostgreSQLって何が違うの?
akagami
PRO
0
160
Featured
See All Featured
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
Abbi's Birthday
coloredviolet
3
9.7k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.8k
Optimizing for Happiness
mojombo
378
71k
The Limits of Empathy - UXLibs8
cassininazir
1
630
Google's AI Overviews - The New Search
badams
0
1.6k
Making the Leap to Tech Lead
cromwellryan
135
10k
WENDY [Excerpt]
tessaabrams
12
39k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
6
1.2k
HDC tutorial
michielstock
2
840
Accessibility Awareness
sabderemane
1
200
The browser strikes back
jonoalderson
0
1.6k
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