useRef
controlled vs uncontrolled element
In principle, React manages the DOM elements. Changes in the DOM derive from a change in state. This is the pattern used for controlled elements.
Sometimes, we want a DOM element to evolve independently (uncontrolled element), its value not being derived from React's state. This pattern avoids React re-renders when the element changes, and is useful when the element changes frequently and when re-renders would affect large parts of the DOM.
Such pattern is called using an uncontrolled (DOM) element.
useRef
allows to request a reference to such an uncontrolled element, so that we may read or set its value at arbitrary time using regular DOM APIs.
Such reference persists across renders and is only discarded when the DOM elements unmounts.
get a reference to an uncontrolled DOM element
In this example, we request a reference to the <input>
DOM element, so that keystrokes do not trigger a React re-render.
const myInput = useRef<HTMLInputElement>(null)
// ..
<input ref={myInput}/>
To get better autocomplete later on when we use the reference, We indicate the element's DOM type as a type parameter. The type can be as broad as HTMLElement, but in this example it is narrowed down to the more accurate HTMLInputElement.
We don't need to indicate null as a type parameter. React already adds it on our behalf.
use the reference
the current
property start as null because there is no way to get a valid DOM reference before the element is mounted. Later, React assigns the valid DOM reference to current.
myInput.current // the DOM element
// use DOM APIs (not React specific)
myInput.current.innerText
myInput.current.innerHTML
myInput.current.value
other uses
By extension, we may use useRef
to hold any kind of value that persists across renders, and that is to be discarded on unmount. For example, we may store an internal counter that is incremented when the component renders. Because it is not part of the React's state, it's incrementation does not trigger a re-render.