JSTAcademy
0 XP
Dashboard
Crash Courses
useRef, useMemo & useCallback
10 min
Masters+175 XP
Crash Courses · Masters

useRef, useMemo & useCallback

Access DOM elements and optimize performance with React's memoization hooks.
10 min read+175 XP on completionCert: React Crash Course
Tap any word in the text below to start reading from there.

useRef, useMemo & useCallback

These hooks give you fine-grained control over DOM access and re-render behavior.

useRef DOM Access

import { useRef, useEffect } from 'react'

function AutoFocusInput() {
  const inputRef = useRef<HTMLInputElement>(null)

  useEffect(() => {
    inputRef.current?.focus()
  }, [])

  return <input ref={inputRef} type="text" placeholder="Auto-focused" />
}

useRef Stable Values (No Re-render)

function Timer() {
  const [seconds, setSeconds] = useState(0)
  const intervalRef = useRef<NodeJS.Timeout | null>(null)

  function start() {
    intervalRef.current = setInterval(() => {
      setSeconds(prev => prev + 1)
    }, 1000)
  }

  function stop() {
    if (intervalRef.current) clearInterval(intervalRef.current)
  }

  return (
    <div>
      <p>{seconds}s</p>
      <button onClick={start}>Start</button>
      <button onClick={stop}>Stop</button>
    </div>
  )
}

useMemo Expensive Computations

function CourseStats({ courses }: { courses: Course[] }) {
  // Recomputes only when courses changes
  const stats = useMemo(() => ({
    total: courses.length,
    totalXp: courses.reduce((sum, c) => sum + c.xp, 0),
    byTrack: courses.reduce((acc, c) => {
      acc[c.track] = (acc[c.track] || 0) + 1
      return acc
    }, {} as Record<string, number>),
  }), [courses])

  return <StatsDisplay stats={stats} />
}

useCallback Stable Function References

function SearchBar({ onSearch }: { onSearch: (q: string) => void }) {
  const [query, setQuery] = useState('')

  // Without useCallback: new function on every render, child re-renders unnecessarily
  const handleSearch = useCallback(() => {
    onSearch(query)
  }, [query, onSearch])

  return (
    <div>
      <input value={query} onChange={e => setQuery(e.target.value)} />
      <SearchButton onClick={handleSearch} />
    </div>
  )
}

const SearchButton = React.memo(({ onClick }: { onClick: () => void }) => (
  <button onClick={onClick}>Search</button>
))
0%