Raygun is the best tool for catching and resolving bugs before they crash prod. We use it at ui.dev and it’s been super helpful.
import { useRef, useEffect } from 'react' import {Modal, ModalHeader, ModalBody, ModalFooter} from '../components/Modal' export default function InputModal({isOpen, close}) { const inputRef = useRef(null) useEffect(() => { if (isOpen) { inputRef.focus() } },[isOpen]) return ( <Modal isOpen={isOpen}> <ModalHeader> <h3>What is your name?</h3> </ModalHeader> <ModalBody> <input name="name" ref={inputRef} /> </ModalBody> <ModalFooter> <Button onClick={() => close()}>Close</Button> </ModalFooter> </Modal> ) }
React treats the ref as a “box” that can hold a mutable value in it’s .current property, including DOM elements. Since React needs a way to update the ref’s value without completely overriding it, the ref itself is an object with a mutable .current property that can be changed any time without changing the object reference.
The bug happens when we try to .focus() the inputRef. The input DOM element is stored in the .current property, so the correct way to focus the input is to call inputRef.current.focus().
Here’s the solution -
export default function InputModal({isOpen, close}) { const inputRef = useRef(null) useEffect(() => { if (isOpen) { inputRef.current.focus() } },[isOpen]) // ... }
Refs can store more than just DOM elements - they can store any value a component needs to hold on to without causing a re-render whenever the value changes.