forwardRef allows parent components to access child component refs.
Code:
1import { forwardRef, useRef, useImperativeHandle } from "react";23// Simple forwarding4const FancyInput = forwardRef<HTMLInputElement>((props, ref) => {5 return <input ref={ref} className="fancy" {...props} />;6});78function Parent() {9 const inputRef = useRef<HTMLInputElement>(null);1011 const focusInput = () => {12 inputRef.current?.focus();13 };1415 return (16 <div>17 <FancyInput ref={inputRef} />18 <button onClick={focusInput}>Focus</button>19 </div>20 );21}
With useImperativeHandle:
1interface InputHandle {2 focus: () => void;3 clear: () => void;4}56const ControlledInput = forwardRef<InputHandle>((props, ref) => {7 const inputRef = useRef<HTMLInputElement>(null);89 useImperativeHandle(ref, () => ({10 focus: () => inputRef.current?.focus(),11 clear: () => {12 if (inputRef.current) inputRef.current.value = "";13 },14 }));1516 return <input ref={inputRef} {...props} />;17});1819// Parent can only call focus() and clear()20function Form() {21 const inputRef = useRef<InputHandle>(null);2223 return (24 <>25 <ControlledInput ref={inputRef} />26 <button onClick={() => inputRef.current?.focus()}>Focus</button>27 <button onClick={() => inputRef.current?.clear()}>Clear</button>28 </>29 );30}
React 19: No longer need forwardRef — ref is passed as regular prop.
When to use: