如何在 React 中正确使用 useRef 来访问子组件的 DOM 节点?
如何在 React 中正确使用 useRef 来访问子组件的 DOM 节点?
回答与解析:
在 React 中,useRef 本身不能直接用于访问函数组件(子组件)的 DOM 节点,因为函数组件没有实例。若要从父组件访问子组件内部的 DOM 元素,需使用 forwardRef 和 useImperativeHandle。
正确做法如下:
- 子组件使用 React.forwardRef 包裹,并通过 ref 接收父组件传递的引用;
- 在子组件内部,使用 useRef 创建对实际 DOM 节点的引用;
- 使用 useImperativeHandle 暴露需要让父组件访问的方法或 DOM 节点。
示例代码:
// 子组件
import { forwardRef, useRef, useImperativeHandle } from 'react';
const Child = forwardRef((props, ref) => {
const inputRef = useRef(null);
useImperativeHandle(ref, () => ({
focus: () => inputRef.current.focus(),
getInputElement: () => inputRef.current
}));
return <input ref={inputRef} />;
});
// 父组件
const Parent = () => {
const childRef = useRef();
const handleClick = () => {
childRef.current.focus(); // 调用子组件暴露的方法
};
return (
<div>
<Child ref={childRef} />
<button onClick={handleClick}>Focus Input</button>
</div>
);
};
关键点解析:
- 直接给函数组件添加 ref 会报错或无效;
- forwardRef 使得 ref 可以被传递到函数组件内部;
- useImperativeHandle 控制暴露给父组件的 API,避免直接暴露整个 DOM 节点(更安全可控);
- 此模式常用于表单控件、动画组件、自定义焦点管理等场景。
注意:应尽量避免过度使用 ref 操作 DOM,优先考虑通过状态和 props 实现声明式 UI。

发表评论 (审核通过后显示评论):