React - useRef: References and Mutable Values
It allows you to directly access the DOM or store mutable values that don't trigger a re-render. It's your Swiss Army knife for stepping outside the React paradigm when necessary!
What is useRef?
The Two Main Uses
- DOM References: Directly access HTML elements
- ๐พ Mutable Values: Store data that doesn't cause a re-render
Difference with useState
import { useState, useRef, useEffect } from 'react'
function StateVsRef() {
const [stateCount, setStateCount] = useState(0)
const refCount = useRef(0)
const renderCount = useRef(0)
// Count the renders
renderCount.current++
const incrementState = () => {
setStateCount(prev => prev + 1) // Triggers a re-render
}
const incrementRef = () => {
refCount.current++ // NO re-render!
console.log('Ref count:', refCount.current)
}
return (
<div>
<h3>State vs Ref</h3>
<p>Number of renders: {renderCount.current}</p>
<p>State count: {stateCount} (triggers re-render)</p>
<p>Ref count: {refCount.current} (NO re-render)</p>
<button onClick={incrementState}>
Increment State (re-render)
</button>
<button onClick={incrementRef}>
Increment Ref (no re-render)
</button>
</div>
)
}
useRef for the DOM
Accessing HTML Elements
function DomReferences() {
const inputRef = useRef(null)
const textAreaRef = useRef(null)
const fileInputRef = useRef(null)
const videoRef = useRef(null)
const focusInput = () => {
inputRef.current.focus()
}
const clearTextArea = () => {
textAreaRef.current.value = ''
textAreaRef.current.focus()
}
const triggerFileSelect = () => {
fileInputRef.current.click()
}
const playVideo = () => {
videoRef.current.play()
}
const pauseVideo = () => {
videoRef.current.pause()
}
const handleFileChange = (e) => {
const file = e.target.files[0]
if (file) {
console.log('Selected file:', file.name)
}
}
return (
<div>
<h3>DOM References</h3>
<div>
<h4>Input with focus</h4>
<input
ref={inputRef}
placeholder="Click the button to focus me"
/>
<button onClick={focusInput}>Focus Input</button>
</div>
<div>
<h4>TextArea with clear</h4>
<textarea
ref={textAreaRef}
placeholder="Write something..."
rows={3}
/>
<br />
<button onClick={clearTextArea}>Clear & Focus</button>
</div>
<div>
<h4>Hidden File Input</h4>
<input
ref={fileInputRef}
type="file"
style={{ display: 'none' }}
onChange={handleFileChange}
/>
<button onClick={triggerFileSelect}>๐ Select file</button>
</div>
<div>
<h4>Video control</h4>
<video
ref={videoRef}
width="300"
controls
>
<source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4" />
</video>
<br />
<button onClick={playVideo}>Play</button>
<button onClick={pauseVideo}>โธ๏ธ Pause</button>
</div>
</div>
)
}