React - useRef : Références et Valeurs Mutables

Il te permet d'accéder directement au DOM ou de stocker des valeurs mutables qui ne déclenchent pas de re-render. C'est ton couteau suisse pour sortir du paradigme React quand nécessaire !


Qu'est-ce que useRef ?

Les Deux Usages Principaux

  1. Références DOM : Accéder directement aux éléments HTML
  2. 💾 Valeurs mutables : Stocker des données qui ne causent pas de re-render

Différence avec useState

import { useState, useRef, useEffect } from 'react'

function StateVsRef() {
  const [stateCount, setStateCount] = useState(0)
  const refCount = useRef(0)
  const renderCount = useRef(0)

  // Compter les renders
  renderCount.current++

  const incrementState = () => {
    setStateCount(prev => prev + 1) // Déclenche un re-render
  }

  const incrementRef = () => {
    refCount.current++ // PAS de re-render !
    console.log('Ref count:', refCount.current)
  }

  return (
    <div>
      <h3>State vs Ref</h3>
      <p>Nombre de renders: {renderCount.current}</p>
      <p>State count: {stateCount} (déclenche re-render)</p>
      <p>Ref count: {refCount.current} (PAS de re-render)</p>
      
      <button onClick={incrementState}>
        Increment State (re-render)
      </button>
      <button onClick={incrementRef}>
        Increment Ref (pas de re-render)
      </button>
    </div>
  )
}

useRef pour le DOM

Accès aux Éléments HTML

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('Fichier sélectionné:', file.name)
    }
  }

  return (
    <div>
      <h3>Références DOM</h3>
      
      <div>
        <h4>Input avec focus</h4>
        <input 
          ref={inputRef} 
          placeholder="Clique le bouton pour me focus" 
        />
        <button onClick={focusInput}>Focus Input</button>
      </div>

      <div>
        <h4>TextArea avec clear</h4>
        <textarea 
          ref={textAreaRef}
          placeholder="Écris quelque chose..."
          rows={3}
        />
        <br />
        <button onClick={clearTextArea}>Clear & Focus</button>
      </div>

      <div>
        <h4>File Input caché</h4>
        <input 
          ref={fileInputRef}
          type="file"
          style={{ display: 'none' }}
          onChange={handleFileChange}
        />
        <button onClick={triggerFileSelect}>📁 Sélectionner fichier</button>
      </div>

      <div>
        <h4>Contrôle vidéo</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>
  )
}

Ressources Pour Aller Plus Loin