refs are a way to get direct access to a DOM element or to a component method. forwardRef is a way to pass a ref through a component to its child element.
Simple analogy: Imagine you are at a parking lot.
useRef — reference to DOM:
1function Form() {2 const inputRef = useRef(null);34 useEffect(() => {5 inputRef.current.focus(); // Focus on input on load6 }, []);78 return <input ref={inputRef} />;9}
useRef — reference to a value (does not cause re-render): Unlike state, changing ref does NOT cause re-rendering.
1function Timer() {2 const countRef = useRef(0);34 useEffect(() => {5 const timer = setInterval(() => {6 countRef.current++;7 }, 1000);8 return () => clearInterval(timer);9 }, []);10}
forwardRef — passing ref to child component:
1const Input = forwardRef((props, ref) => {2 return <input ref={ref} {...props} />;3});45function Form() {6 const inputRef = useRef(null);7 return <Input ref={inputRef} />; // ref is "passed through" to input8}
useImperativeHandle — configuring API via ref: Allows you to decide what will be available to the parent via ref.
1const Video = forwardRef((props, ref) => {2 const videoRef = useRef(null);34 useImperativeHandle(ref, () => ({5 play: () => videoRef.current.play(),6 pause: () => videoRef.current.pause(),7 }));89 return <video ref={videoRef} />;10});