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
ReactのFocus制御で学んだ useLayoutEffectとCallback ref
Search
Sawa Yoshioka
October 03, 2026
Technology
59
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ReactのFocus制御で学んだ useLayoutEffectとCallback ref
2026/10/2(金)のReact Tokyo LTで発表したスライドです。
Sawa Yoshioka
October 03, 2026
Other Decks in Technology
See All in Technology
『SAR衛星データ解析入門』のご紹介とその応用
syuchimu
0
120
Rust で関数型ドメインモデリング
takonda
0
140
USB PDを使ってスマホを労わりたい
raspython3
0
180
DGX Spark でどこまでハッキングができるのか?
kash1064
3
1.3k
DevelopersIO 2026 知識の地図を描く ─ オントロジーとは何か?
ishikawa_satoru
1
1.7k
Conditional PED-ANOVA: Hyperparameter Importance in Hierarchical & Dynamic Search Spaces
pfn
PRO
0
130
Rustuna: Rustによる高速なOptuna実装
pfn
PRO
0
190
PHPカンファレンス関西の招待状 / Invitation to PHP Conference Kansai
ykanoh
0
110
"優秀な誰か"の下位互換にならないために
yut0naga1_fa
1
1.8k
子育てエンジニアの可処分時間が減っても成長を諦めない戦い方
sudoakiy
6
4.6k
LambdaWebFunctionsを試してみた / exploring-lambda-web-functions
koukihosaka
1
340
Classmethod Company Deck
satoshi7
1
680
Featured
See All Featured
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
370
Typedesign – Prime Four
hannesfritz
42
3.2k
Code Reviewing Like a Champion
maltzj
529
40k
Designing for Timeless Needs
cassininazir
1
530
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
320
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.6k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
2
410
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
50
10k
Code Review Best Practice
trishagee
74
20k
How STYLIGHT went responsive
nonsquared
100
6.3k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.7k
Transcript
ReactのFocus制御で学んだ useLayoutEffectと Callback ref さっちゃん / 吉岡 爽(@sawa__yoshioka) 2026/10/2 React
Tokyo LT
whoami 吉岡 爽(Sawa Yoshioka) X: @sawa__yoshioka 愛媛県出身 2026/04 株式会社サイバーエージェントに入社 AI事業本部
株式会社AI Shift配属 #webフロント #陶芸 #26歳 #瓶ビール #オレンジワイン 初登壇です!🙌
CyberAgent / AI Shiftとは
None
None
None
None
背景:今回触った機能
今回触った機能:権限割当の編集ダイアログ • ユーザーに「権限× 影響範 囲」を増減可能な複数行で 割り当てるダイアログ • 「+割り当てを追加」ボタ ンで、未選択の空行を1行 追加する
[画像: ロール割当編集ダイアログのスクショ] 技術スタック👇 React 19 react-aria Tailwind CSS react-hook-form
背景:バグと修正
バグと修正:行が増えると見切れる 👇 Before 👇 After
追加した行にフォーカスしたい...!! ←ここから本題です
やりたいこと:追加行への focus 制御 1 2 「割当を追加」を押す 3 その行の権限欄にフォー 未選択の空行が1行増える ��
�� カスが移り、すぐ選べる 「DOM が更新された直後に フォーカスしたい…… • 以前は、使っていない組み合わせが自動で埋まり、意図し ない権限のまま保存できてしまっていた → 空行を追加して選んでもらう形に変更 • focus() は、スクロール領域の外にある要素も画面内まで 自動でスクロールしてくれる そうだ、useLayoutEffect だ!」
最初の実装
最初の実装:useLayoutEffectでfocusする 「割当を追加」で未選択の空行が増える → その行のロール欄にすぐフォーカスを移したい const listRef = useRef<HTMLDivElement>(null); const shouldFocusAddedRow
= useRef(false); const appendAssignment = () => { shouldFocusAddedRow.current = true; addAssignment(); }; useLayoutEffect(() => { if (!shouldFocusAddedRow.current) return; 動いた!めでたしめでたし……? shouldFocusAddedRow.current = false; listRef.current?.lastElementChild?.querySelector("button")?.focus(); }, [fields.length]);
愛のムチ(レビュー)
レビュアーからの愛の鞭 レビューコメント [IMO] useLayoutEffect はかなり重たいので可能な限り使用を避けたい気持ち です 🙋 この用途なら effect を使わずに
追加された最後の行だけ callback ref で mount 時に focus する 形でも実現できそうです。 愛のムチあざっす!!!
深掘り
深掘り:なぜEffectはいらなかったのか ⚡ 同期的に実行 Render (何を描くか計算) DOM 更新 ref の付与 /
useLayoutEffect Paint useEffect (画面に描画) 📌 同じタイミング・Paint の前 callback ref 版 💡 useLayoutEffect 版 要素の探し方 lastElementChild → querySelector で探す 対象の要素が自分自身を受け取る マークアップへの依存 「最後の子の最初の button」構造に暗黙依存 依存しない 仕組み 依存配列 [fields.length] で同期 Effect 不要 🔑 タイミングは同じ。違いは「Effect で DOM を探しに行く必要があるか」 出典:react.dev「You Might Not Need an Effect」/ https://ja.react.dev/learn/manipulating-the-dom-with-refs ・
どのように直したか
修正:callback ref + フラグで追加した行にfocus {fields. map((field, index) => { const
isLastRow = index === fields.length - 1; return ( <SelectMenu /* ❶ refに関数を渡す */ ref={(node) => { if ( node != null && isLastRow && shouldFocusAddedRow.current ) { /* ❷ インライン関数の制御 */ shouldFocusAddedRow.current = false; node.focus(); } }} // ... 眩しい.......!!!!!!! /> ); })} 1 ref に関数を渡す DOM に付いた瞬間に直接 node を受け取れる 2 インライン関数の制御 再レンダリング毎の実行を防ぐため、フラグを下ろし て「1回だけ」に制限 3 ref.current の読み出し規則 レンダー中ではなく、callback の中で安全に読む (Reactのルール) [GIF: 追加 → 新しい行にフォーカス] ✨ 挙動は変わらず、Effect と DOM 探索が消えた
学んだこと・まとめ
学んだこと・まとめ ✅ マウント時に DOM を触るだけなら、 Effect ではなく callback ref ✅
インラインの callback ref は毎回呼ばれる → 「1回だけ」はフラグで守る ✅ useLayoutEffect は「描画前に測らないとちらつく」ときの道具 (同じ PR でも、ポップオーバーの幅を測る処理では useLayoutEffect を残した) 💡 react-hook-form の shouldFocus を使えば もっと簡単だったかも? ありがとうございました!