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
useImperativeHandleで理解する クロージャと評価タイミング
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Tasuku Watanabe
January 07, 2026
Programming
110
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
580
axiosで作る:ファイルアップロード体験を改善する「Progress Toast」
tasukuwatanabe
0
620
Other Decks in Programming
See All in Programming
思考垂れ流し開発 ~音声入力 × AIエージェント × 開発ハーネスによる試行錯誤~
npostring
0
1.1k
巨大モノリシックアプリ モダン化大作戦
ktcryomm
0
590
Laravelのアプリケーションをどこにデプロイするか #ツナギメオフライン.9
akase244
0
120
Deep dive into the select statement (GopherCon UK)
jespino
0
170
AgentCore CLI で進化した AWS での AI エージェントの作り方 : 必要な機能を必要な時に
icoxfog417
PRO
2
280
MIZARU@SPAJAM2026 第二回予選
1901drama
0
110
XP祭りでしか伝わらないフリップネタ #xpjug
murabayashi
0
130
LoopHub - ローカルで動く GitHub で、AI と共同開発
jugyo
1
490
新卒PdEのリアル
ryu1013
1
480
Vibes Containers 〜AIで変わるコンテナ設計と運用〜
tkikuc
3
520
AIは賢い。でも実行環境は? CLIおじさんがAI時代に伝えたいこと ~ CLIおじさんがAI時代に伝えたいこと ~
curekoshimizu
1
230
初心者DevRelとして参加者だった私が、DevRel Talks!#2に登壇するまでにしてきたこと
sokohirai
0
360
Featured
See All Featured
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
470
My Coaching Mixtape
mlcsv
0
310
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
600
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
2
3.8k
Producing Creativity
orderedlist
PRO
348
41k
Deep Space Network (abreviated)
tonyrice
0
300
Mind Mapping
helmedeiros
1
350
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
380
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
890
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.3k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
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
まとめ 変数に代入 → クロージャにキャプチャされ、値や参照が固定される。 評価タイミングを意識して実装しましょう。