useRef
What is it
Referencing a value
that needs to persist that is NOT needed for rendering
.
- Modifying the
current
property of auseRef
object does not trigger a re-render
Commonly used for storing references to DOM elements, timers, previous state or props, and any value that should be retained through the component's lifecycle without triggering re-rendering.
// syntax const ref = useRef(initialValue); // usage import { useRef } from 'react'; function MyComponent() { const intervalRef = useRef(0); const inputRef = useRef(null); // ... };
Return Value
Returns an object
with a single current
property.
current
is initially set to a value passed toinitialValue
.
Subsequent mutation to Ref needs reassignment of the property.
// reassign the Ref someRef.current = newValue; // can be done in function function handleStartClick() { const intervalId = setInterval(() => { // ... }, 1000); intervalRef.current = intervalId; }
Behavior
Changing a ref
does not trigger a re-render.
- unlike
state
variable which triggers a re-render.
Can store information between re-renders
- unlike regular variables which reset on every render), ref values are preserved between renders.
Information is local to each copy of your component
- unlike the variables outside which are shared
Strategies
useRef
can become useful when directly manipulating DOM content
React updates the reference to point to the element when passed to ref
attribute
- When React creaets a DOM node for theis element, it attaches the reference to the node. This is a native feature/support of React.
// initialize with DOM element type to reference const headerDropdown = useRef<HTMLDetailsElement>(null); return( <> {/* ref must be placed directly on jsx element */} <details className="w-full" ref={headerDropdown}> Text </details> <button onClick={() => { // current is used to access the ref value headerDropdown.current &&headerDropdown.current.removeAttribute('open')! }} > "button" </button> </> )
useRef
in Context
import { createContext, createRef, useContext } from "react"; const VideoContext = createContext(); const videoRef = createRef(); export const VideoContextProvider = (props) => { return ( <VideoContext.Provider value={videoRef}> {props.children} </VideoContext.Provider> ); }; export const useVideoContext = () => useContext(VideoContext);