如何将Ref向下传递给子组件?子组件如何获取父组件的Ref以获取其宽度?
React Ref 相关问题解答
1. 如何将一个 ref 向下转发到子组件?
这正是 forwardRef 方法的核心用途!它能让父组件把自己创建的 ref 传递给子组件内部的 DOM 元素或组件实例,步骤很清晰:
- 首先用
React.forwardRef()包裹子组件,这样子组件就能接收额外的ref参数(第二个参数,第一个是常规 props)。 - 然后把这个
ref绑定到子组件内部你需要访问的 DOM 节点或者类组件实例上。
举个直观的例子:
子组件(用 forwardRef 包裹)
const ChildComponent = React.forwardRef((props, ref) => { // 将父组件传递的 ref 绑定到内部的 input 元素 return <input ref={ref} type="text" placeholder="试试点击下方按钮聚焦我" />; });
父组件(传递 ref 并操作子组件元素)
function ParentComponent() { const inputRef = useRef(null); const focusInput = () => { inputRef.current?.focus(); // 直接操作子组件里的 input 元素 }; return ( <div> <ChildComponent ref={inputRef} /> <button onClick={focusInput}>聚焦输入框</button> </div> ); }
这样父组件就能通过自己创建的 inputRef 直接控制子组件内部的 DOM 元素了。
2. 如何把父组件的 ref 传递给子组件,让子组件获取父组件的宽度?
这个场景和 forwardRef 的方向正好相反——不是子组件暴露自己的 ref 给父组件,而是父组件把自己的 ref 传给子组件。其实不用复杂的 API,直接把父组件的 ref 作为普通 props 传给子组件就行。
具体操作步骤:
- 父组件创建自己的 ref,绑定到自身的容器元素上。
- 把这个 ref 作为 props 传递给子组件。
- 子组件里通过
useEffect监听,当 ref 绑定到真实 DOM 后获取父组件的宽度,还可以监听窗口 resize 事件来实时更新宽度。
看代码示例:
父组件
function ParentComponent() { const parentRef = useRef(null); return ( <div ref={parentRef} style={{ width: "70%", border: "1px solid #eee", padding: "1rem", margin: "0 auto" }} > <ChildComponent parentRef={parentRef} /> </div> ); }
子组件
function ChildComponent({ parentRef }) { const [parentWidth, setParentWidth] = useState(0); useEffect(() => { // 定义获取父组件宽度的函数 const updateParentWidth = () => { if (parentRef.current) { setParentWidth(parentRef.current.offsetWidth); } }; // 组件挂载后初始化获取宽度 updateParentWidth(); // 监听窗口 resize,宽度变化时更新 window.addEventListener("resize", updateParentWidth); // 组件卸载时清理监听事件 return () => { window.removeEventListener("resize", updateParentWidth); }; }, [parentRef]); return <p>父组件当前宽度:{parentWidth}px</p>; }
这里要注意:必须在 useEffect 里处理,因为组件挂载后 ref 才会绑定到真实 DOM,直接在渲染阶段访问 parentRef.current 大概率会拿到 null。加上 resize 监听,能保证父组件宽度变化时子组件能实时同步数据。
内容的提问来源于stack exchange,提问作者Lofty Brambles




