Chapter 3 of 4
Forwarding Refs
Letting a parent reach the DOM node inside your component.
A ref placed on your own component does not reach the DOM, because ref is not a normal prop. forwardRef passes it through to the element you choose.
import { forwardRef, useRef } from "react";
const TextField = forwardRef(function TextField({ label, ...rest }, ref) {
return (
<label>
{label}
<input ref={ref} {...rest} />
</label>
);
});
function Form() {
const emailRef = useRef(null);
return (
<form onSubmit={() => emailRef.current.focus()}>
<TextField ref={emailRef} label="Email" />
</form>
);
}Exposing a limited API with useImperativeHandle
Sometimes you want the parent to call specific methods rather than get the raw node. useImperativeHandle lets you decide what ref.current contains.
const VideoPlayer = forwardRef(function VideoPlayer(props, ref) {
const videoRef = useRef(null);
useImperativeHandle(ref, () => ({
play: () => videoRef.current.play(),
pause: () => videoRef.current.pause(),
}), []);
return <video ref={videoRef} src={props.src} />;
});
// The parent gets play and pause, and nothing else
playerRef.current.play();Build a small mutable box
Write createRef so it returns an object with a current property initialised to the given value, and so assigning to current works.