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
Tasuku Watanabe
January 07, 2026
Programming
89
1
Share
useImperativeHandleで理解する クロージャと評価タイミング
Tasuku Watanabe
January 07, 2026
More Decks by Tasuku Watanabe
See All by Tasuku Watanabe
モックわからないマン卒業記 ~振る舞いを起点に見直した、フロントエンドテストにおけるモックの使いどころ~
tasukuwatanabe
3
490
axiosで作る:ファイルアップロード体験を改善する「Progress Toast」
tasukuwatanabe
0
560
Other Decks in Programming
See All in Programming
Spec-Driven Development with AI Agents (Workshop, May 2026)
antonarhipov
4
430
Kubernetesを使わない環境にもCloud Nativeなデプロイを実現する / Enabling Cloud Native deployments without the complexity of Kubernetes
linyows
3
510
Transactional Change Stream Processing With Debezium and Apache Flink
gunnarmorling
1
120
バックエンドにElysiaJSを採用して気付いた、良い点・悪い点
wanko_it
1
160
Modding RubyKaigi for Myself
yui_knk
0
400
tsserverとは何だったのか、これからどうなるのか
nowaki28
1
350
SkillsをS3 Filesに置く時のあれこれ
watany
4
1.7k
Sans tests, vos agents ne sont pas fiables
nabondance
0
150
タクシーアプリ『GO』の バックエンド開発のおける AI利活用と若者のすべて
pyama86
2
1.5k
今さら聞けないCancellationToken
htkym
0
170
要はバランスからの卒業 #yumemi_grow
kajitack
0
190
TSKaigi2026-静的解析への投資がAI時代のコード品質を支える ── カスタムESLintルールの設計と運用
hayatokudou
5
1k
Featured
See All Featured
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
570
Measuring & Analyzing Core Web Vitals
bluesmoon
9
830
Paper Plane (Part 1)
katiecoart
PRO
0
7.8k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
2k
Test your architecture with Archunit
thirion
1
2.2k
RailsConf 2023
tenderlove
30
1.4k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Crafting Experiences
bethany
1
150
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Believing is Seeing
oripsolob
1
130
Evolving SEO for Evolving Search Engines
ryanjones
0
200
Testing 201, or: Great Expectations
jmmastey
46
8.2k
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
まとめ 変数に代入 → クロージャにキャプチャされ、値や参照が固定される。 評価タイミングを意識して実装しましょう。