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
Recoilを剥がしている話
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
kirik
December 11, 2024
Programming
12k
5
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Recoilを剥がしている話
2024/12/10に開催された3社合同フロントエンド合同勉強会で話した内容
https://prtimes.connpass.com/event/335335/
kirik
December 11, 2024
More Decks by kirik
See All by kirik
Tiptapで校正機能を作った時に考えたこと
kirik
0
79
Recoil脱却の現状と挑戦
kirik
2
860
Tiptapで実現する堅牢で柔軟なエディター開発
kirik
1
460
Other Decks in Programming
See All in Programming
Webフレームワークの ベンチマークについて
yusukebe
0
170
Inside Stream API
skrb
1
730
その問い、本当に正しいですか?AI時代のエンジニアに必要な哲学と認知科学 / ai-philosophy-cognitive-science
minodriven
11
5.8k
Signal Forms: Details & Live Coding @enterJS 2026 in Mannheim
manfredsteyer
PRO
0
160
並列実装の現場、2ヶ月間実務でAIを使い倒したAIもPCも私も限界が近い
ming_ayami
0
130
さぁV100、メモリをお食べ・・・
nilpe
0
140
TypeScript+Orvalで実現する型安全かつ堅牢でスケーラブルなマルチチャネル通知基盤 / TSKaigi Night talks ~after conference~
d0riven
0
350
Lessons from Spec-Driven Development
simas
PRO
0
210
Even G2とAWSで推しのエージェントを召喚しよう!
har1101
1
120
AIで効率化できた業務・日常
ochtum
0
140
LLMによるContent Moderationの本番運用の裏側と品質担保への挑戦
suikabar
3
700
過去最大のMCPアップデート! 2026-07-28 RC版の謎に迫る
licux
6
360
Featured
See All Featured
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
160
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
730
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
140
Ethics towards AI in product and experience design
skipperchong
2
310
Facilitating Awesome Meetings
lara
57
7k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
200
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
390
Crafting Experiences
bethany
1
180
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
170
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
62
54k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.5k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Transcript
Recoilを剥がしている話 3社合同フロントエンド合同勉強会 2024/12/10 株式会社PR TIMES @kiririLee
・アプリケーションの状況 ・なぜ剥がしているのか ・何に移行しているのか ・進め方 ・遭遇したパターンと反省点 ・現状の進捗とつらみ
現状のアプリケーションの状況 ・React, Next.jsで構築されたプロジェクトでRecoilに 依存しているプロジェクト数は15 ・フロントエンドチームとしてRecoilの利用方針、設計方針などは なくプロジェクトによって使い方や依存の仕方がバラバラ Global State以外にも非同期処理、localStorageと Reactの同期にも使用されている
なぜ剥がしているのか 🤔
・React 19で動かない ・2023/4/12 からリリースがなく、対応される見込みがない ・Recoilをフォークして自分たちでメンテしていくリソースはない パッチを当てれば動くには動くが プロダクションで動かすには信頼できない
Recoilが依存関係にある限りReact 19へのバージョンアップは できない PR TIMESは17年続いているサービスであり、現在も様々な 新機能が追加され続けている 今後も数年先の機能追加などを考え、継続的に運用していく 必要がある Recoilの依存は将来的な事業運営を困難にするのは明らかで あるためRecoilから脱却する
状態管理は何に移行しているのか 🤨
今後も数年先の機能追加などを考え、継続的に運用していく 必要がある ソフトウェアの持続性を考える必要がある そのためReact公式(標準)のAPIのみで状態管理を行うのが理想 再掲 Recoil を useState, Context で置き換える方針
💪
From To サーバーデータ Recoil, TanStack Query TanStack Query, Context +
useEffect Global State Recoil Context Local State Recoil useState 参考:「3種類」で管理するReactのState戦略 ・非同期処理はTanstack Queryに寄せつつ、 プロジェクトによっては Context + useEffect を使用 ・新規のプロジェクトではRecoilを一切使わない
置き換えたパターンと反省点 🧐
State自体必要ないパターン URLの状態によってコンポーネントを出し分ける実装で URLの状態を Recoil の atom, selector で管理 Setter (setState)がなく、SetterによるUIの更新がない
コンポーネントの再レンダリングごとにURLの状態を見て コンポーネントを出し分ける。State自体削除。 Before After
URLのパラメーターから現在のページを取得 navigatorからUAをみてモバイルかどうか判断 2つのatom(仮実装) Before
2つのatomから合成したselector モバイルデバイスかつ外部共有ページであることを判定するselector Before
Selectorの値によりコンポーネントを出し分ける(仮実装) Setterはなく、参照のみ。 Before
関数を実行して分岐するように修正 After
State自体必要ないパターン Setterを使用していないStateはそもそもStateが必要ない (場合がほとんど) StateのSetterを呼び出した場合のみ更新されるという特性を 活かしてインスタンスを保持するパターンはある
localStorageと同期するパターン Recoil の Atom Effects で localStorage と Stateを同期する実装 localStorageの値を初期値として設定するのはuseStateに
コールバック関数を渡す 更新は、setState のタイミングで localStorage も同時に更新する カスタムhooksを作成し、appからはhooksで更新をする Before After
コードでのイメージ
Selectorで非同期処理をしているパターン Recoil の SelectorでAPIからデータを取得して、さらにそのデータを 別のSelectorで加工(派生状態)してappから参照している実装 APIのデータ取得は useEffect、取得したデータの配布はContext 派生状態は全て削除して、派生状態への変換をカスタムhooksに 切り出す。 Before
After
Selector による APIデータ取得
派生状態 ① string型をDate型に変換 派生状態①からの派生状態② Date型をフォーマットした string型
RecoilのSelectorで派生状態を作ると、その状態にsetState できるようになる。 派生状態① にはDate型で setState する 派生状態② にはフォーマットした日付を setState する
string, Date, format後のstring 、三つのStateが存在する
大きく分けて以下の二つのパターンで置き換えられる。 ・一つのStateに三つの状態をまとめる。 ・状態を一つにしてカスタムhooksで参照するときに加工する
APIデータ取得後に、一つのStateに三つの状態をまとめる。(例)
状態を一つにしてカスタムhooksで参照するときに加工する ・APIからデータ取得後にDate型のみで保存する ・コンポーネントからはカスタムhooksで加工したデータを使う ・setState するときは、毎回Date型に変換して setState する
参照するときのカスタムhooks(例)
更新するときのカスタムhooks(例) Stateの型はDate型一つのため、formatDateToDate関数(仮)で string型をDate型にしてセットする
実際には二つの置き換えパターンのハイブリッド ・一つのオブジェクト(State)に全ての派生状態をまとめると オブジェクトが大きくなってしまう。 ・カスタムhooksは、Stateの参照と更新を行うときにそれぞれ 毎回変換ロジックを書く必要がある。 バランスを見て調整。 selectorで複数のselectorに依存かつ そのselectorにセットしている場合は対応できないため別で 対応が必要。
Selectorがどうしても必要な場面が今の所見当たらない。 ・多くの場合、コンポーネントから参照する際に 複数のStateを集約し、加工するために使う。 カスタムhooksで良いのでは?派生状態にSetterはいらないのでは? ・カスタムhooksの変換ロジックは純粋関数のためテスト しやすい。 カスタムhooksで良いのでは?
現状のつらみと進捗 😀
派生状態がつらい ・派生状態が多い場合、根本のselectorから末端のselectorまで 一気に置き換える必要があり、影響範囲が広くQAが大変。 ・特に根本のSelectorでAPIデータを取得していると それがGlobal Stateとして扱われ、アプリケーション全体に 影響が及びがちになっている。
影響範囲別に3つに分けて進行中 ・影響範囲小: Recoilに依存しているファイル数が10ファイル以下のプロジェクト ・影響範囲中: 20ファイル以下のプロジェクト ・影響範囲大: 依存が特に広い50 〜 100ファイル以上のプロジェクト 進行方法
・影響範囲小 9つのプロジェクトの内7プロジェクト完了 ・影響範囲中 3つのプロジェクトの内、現状どれもまだ手付かず ・影響範囲大 4つのプロジェクトの内、2つのプロジェクトで派生状態に つらみを覚えながら進行中。 進捗
To be continued...