ā¤ Like
šŸ”– Save
šŸ”— Share
Eric Hu
Eric Hu

React Ref Hooks

@thedevspaceio

āš›ļø The Hook That Lets You Touch the DOM

React makes DOM abstract. But sometimes you need to break out of the abstraction and interact with the DOM directly.

This is what refs are for.

āœ… useRef āœ… useImperativeHandle āœ… DOM manipulation āœ… Persisting mutable values

#react #hooks #useref #useimperativehandle #refs #webdev #frontend #coding #tips


Refs let you reference DOM elements and hold values that persist between renders without causing re-renders.

HookDescription
useRefReference a DOM node or persist a mutable value.
useImperativeHandleCustomize the ref exposed to parent components.

useRef

Returns a ref object with a single current property. Updating current does not trigger a re-render.

jsx
const inputRef = useRef(null);

Referencing DOM elements

Attach the ref to an element, then access it via current.

jsx
function InputFocus() {
  const inputRef = useRef(null);
 
  return (
    <>
      <input ref={inputRef} type="text" />
      <button onClick={() => inputRef.current.focus()}>Focus</button>
    </>
  );
}

Persisting mutable values

Store values that can be updated, without causing re-renders, like timers or previous values.

jsx
const intervalRef = useRef(null);
 
function start() {
  intervalRef.current = setInterval(tick, 1000);
}
 
function stop() {
  clearInterval(intervalRef.current);
}

Tracking previous values

Refs persist values between renders, which means you can use it to store the previous value of a prop or state.

jsx
function Counter({ count }) {
  const prevCount = useRef(count);
 
  useEffect(() => {
    prevCount.current = count;
  }, [count]);
 
  return (
    <p>
      Now: {count}, before: {prevCount.current}
    </p>
  );
}

useImperativeHandle

Customize the value exposed when a parent attaches a ref to your component.

jsx
useImperativeHandle(ref, () => ({
  focus: () => inputRef.current.focus(),
}));

Exposing a limited API

Hide internal DOM structure and expose only what parents need.

jsx
function CustomInput({ ref }) {
  const inputRef = useRef(null);
 
  useImperativeHandle(ref, () => ({
    focus: () => inputRef.current.focus(),
    clear: () => (inputRef.current.value = ""),
  }));
 
  return <input ref={inputRef} type="text" />;
}

Only focus() and clear() are exposed to the parent component. The parent cannot access the internal input element directly.

jsx
function Form() {
  const inputRef = useRef(null);
 
  return (
    <>
      <CustomInput ref={inputRef} />
      <button onClick={() => inputRef.current.clear()}>Clear</button>
    </>
  );
}

Full-Stack AI Developer Roadmap

From HTML & CSS to working with AI models, all in one structured roadmap.

@thedevspaceio
www.thedevspace.io