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
useImperativeHandleで理解する クロージャと評価タイミング
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Tasuku Watanabe
January 07, 2026
Programming
97
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
useImperativeHandleで理解する クロージャと評価タイミング
Tasuku Watanabe
January 07, 2026
More Decks by Tasuku Watanabe
See All by Tasuku Watanabe
モックわからないマン卒業記 ~振る舞いを起点に見直した、フロントエンドテストにおけるモックの使いどころ~
tasukuwatanabe
3
530
axiosで作る:ファイルアップロード体験を改善する「Progress Toast」
tasukuwatanabe
0
590
Other Decks in Programming
See All in Programming
なぜ型を書くのか? TSKaigi2026で改めて考える #tskaigi_smarthr
kajitack
0
180
Developing with AI Agents — Codex, Claude Code & Cowork Practical Guide
x5gtrn
PRO
0
1.3k
Spring Security 実践 ─ GraphQL APIで実務に役立つ 認証・認可 を学ぶ
wagyu
0
270
TypeScript+Orvalで実現する型安全かつ堅牢でスケーラブルなマルチチャネル通知基盤 / TSKaigi Night talks ~after conference~
d0riven
0
380
任せる範囲はこう広がった / How the Scope of AI Delegation Has Expanded
nrslib
1
220
トークンをケチるな、設計しろ:GitHub Copilotを賢く使うコンテキスト戦略
ochtum
0
270
Webフレームワークの ベンチマークについて
yusukebe
0
190
Signal Forms: Details & Live Coding @enterJS 2026 in Mannheim
manfredsteyer
PRO
0
210
過去最大のMCPアップデート! 2026-07-28 RC版の謎に迫る
licux
6
430
TSKaigi Night Talks 2026_TypeScriptでサプライチェーンの整合性を型に閉じ込める
geekplus_tech
0
420
Agentic UI
manfredsteyer
PRO
0
220
Javaの型とAI時代に型が大事な理由 / java types and type in AI era
kishida
2
160
Featured
See All Featured
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
180
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
230
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
400
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
1.1k
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
750
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.1k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
Statistics for Hackers
jakevdp
799
230k
Leo the Paperboy
mayatellez
7
1.9k
Are puppies a ranking factor?
jonoalderson
1
3.7k
Unsuck your backbone
ammeep
672
58k
Test your architecture with Archunit
thirion
1
2.3k
Transcript
useImperativeHandleで理解する クロージャと評価タイミング 2026/01/07 MOSH Tech Meetup 株式会社HRBrain 渡邉 佑
株式会社HRBrain 渡邉 佑 新潟県の佐渡島出身 新卒で航海士の道へ進む ウェブ制作やアナリティクスに転向 ボクササイズとサウナが好きです X: @tasuku_web GitHub:
@tasukuwatanabe 1
useImperativeHandleを使ったコンポーネント const VideoPlayer = ({ src, ref }) => {
const videoRef = useRef<HTMLMediaElement>(null) useImperativeHandle(ref, () => ({ get currentTime() { return videoRef.current?.currentTime // 動画の再生位置 } }), []) return <video ref={videoRef} src={src} /> } DOMへの直接アクセスを隠蔽し、必要な機能だけを公開 2
親コンポーネントでの使用 const ParentComponent = () => { const parentRef =
useRef<VideoPlayerRef>(null) const handleClick = () => { parentRef.current?.currentTime // アクセス可能 parentRef.current?.duration // アクセス不可 } return ( <> <VideoPlayer src="video.mp4" ref={parentRef} /> <button onClick={handleClick}>クリック</button> </> ) } 公開するプロパティとメソッドを子コンポーネント側で制限している 3
実装中に遭遇した問題: 「取得される currentTime が常に 0 のまま更新されない」 原因は「値の評価タイミング」にあった 4
NG例①:プロパティの値を変数に代入する useImperativeHandle(parentRef, () => { const currentTime = videoRef.current?.currentTime //
0 const volume = videoRef.current?.volume // 1 return { get currentTime() { return currentTime }, // 0で固定される get volume() { return volume }, // 1で固定される } }, []) 問題: useImperativeHandle実行時に値が評価され、クロージャに固定される → 変数に代入した時点で値がコピーされるため、動画が再生されても更新されない 5
NG例②:DOMへの参照を変数に代入する useImperativeHandle(parentRef, () => { const video = videoRef.current return
{ get currentTime() { return video?.currentTime }, get volume() { return video?.volume }, } }, []) 問題: DOMのマウントが未完了だと、クロージャによって const video = null がキャプチ ャされ、DOMマウント完了後も変数は null のままになる ※ 条件付きレンダリングや遅延マウントなどで発生する可能性 6
解決策:getter内でrefを直接参照 useImperativeHandle(parentRef, () => ({ get currentTime() { return videoRef.current?.currentTime
}, get volume() { return videoRef.current?.volume } }), []) 変数に代入せず、getter内で毎回 videoRef.current を参照 → getter呼び出し時に評価されるため、最新の値を取得でき、マウントタイミングに も依存しない 7
まとめ 変数に代入 → クロージャにキャプチャされ、値や参照が固定される。 評価タイミングを意識して実装しましょう。