Từ React 19, function component nhận ref như prop bình thường, nên phần lớn chỗ dùng forwardRef chỉ để chuyển ref xuống DOM đều có thể bỏ:
jsx
// React 19
function TextInput({ ref, ...props }) {
return <input ref={ref} {...props} />
}forwardRef vẫn chạy (bị đánh dấu deprecated, có codemod để chuyển) — thư viện cần hỗ trợ React 18 vẫn phải giữ.
useImperativeHandle không bị thay thế: nó dùng khi bạn muốn ref trỏ tới một API do mình định nghĩa thay vì DOM node trần, để không lộ toàn bộ element ra ngoài:
jsx
function VideoPlayer({ ref }) {
const videoRef = useRef(null)
useImperativeHandle(ref, () => ({
play: () => videoRef.current.play(),
seek: (t) => { videoRef.current.currentTime = t },
}), [])
return <video ref={videoRef} />
}Nguyên tắc dùng: chỉ mở ra những hành động mệnh lệnh mà props không diễn đạt được — focus, scroll, play, mở/đóng dialog.
- Trạng thái hiển thị vẫn nên đi qua props.
- Lạm dụng imperative handle làm luồng dữ liệu khó theo dõi vì cha điều khiển con ngoài cơ chế render.