useRef
What is it
Referencing a value that needs to persist that is NOT needed for rendering.
- Modifying the currentproperty of auseRefobject 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.
- currentis initially set to a value passed to- initialValue.
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 statevariable 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);