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

  1. DOM References: Directly access HTML elements
  2. ๐Ÿ’พ 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>
  )
}

Resources For Further Exploration