0Pricing
React Academy · 课时

forwardRef:向父组件暴露 DOM 引用

学习 forwardRef 如何让父组件访问子组件的 DOM 节点或组件实例。

forwardRef:向父组件暴露 DOM 引用 是 CoddyKit 上的免费 React Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。

引用的含义与默认限制

引用是一种持有 DOM 节点或组件实例引用的方式,它会跨渲染持久存在,但不会触发重新渲染。您可以通过 ref 属性附加引用,React 会在提交到 DOM 后将其当前值填入。

关键在于,您不能像给 div 添加引用那样,将引用附加到函数组件上。默认情况下,父组件无法访问子组件内部的 DOM 节点,因为引用不会像普通属性那样向下传递。

forwardRef 包装组件

React.forwardRef 让组件能够接收来自父组件的引用,并将其继续转发给自己的某个元素。它会包装您的组件函数,并改变函数签名,使引用作为第二个参数与属性一起传入。

这是向调用方组件暴露内部 DOM 节点的官方应急出口,可将原本不透明的子组件变成父组件能够直接引用其元素的组件。

forwardRef 的签名

被包装的函数接收两个参数:(props, ref)。第一个是通常的属性对象,第二个是转发的引用。随后将该引用展开或附加到要暴露的元素上,例如在内部输入框上写作 ref={ref}。

请记住,只有用 forwardRef 包装的组件才会接收第二个参数。普通函数组件即使将 ref 列为第二个参数,也只会收到 undefined。

使用场景:从父组件聚焦子组件输入框

经典示例是一个可复用的文本字段组件,您希望父组件能够聚焦其中的内部输入框。用 forwardRef 包装该字段,并将转发的引用附加到基础输入元素后,父组件就可以直接调用 focus。

这样既能保持字段组件的可复用性,又能在确实需要的地方提供受控的命令式访问,例如在表单挂载时聚焦第一个字段。

测量子元素

转发的引用还支持测量。父组件可以读取通过 forwardRef 获取的子元素的 offsetWidth、offsetHeight,或调用 getBoundingClientRect。

这对于工具提示、弹出层和布局计算非常有用:父组件必须先知道内部元素实际渲染出的精确尺寸或位置,才能决定相对于它应如何放置其他内容。

调用滚动方法

由于转发的引用指向真实的 DOM 节点,父组件可以调用其原生 DOM 方法。对转发的列表项调用 scrollIntoView,可以平滑地将其滚动到可视区域;对转发的滚动容器调用 scrollTo,则可以重新定位其内容。

这些都是没有简洁声明式等价方式的命令式操作,而这正是引用适合处理的交互类型。

跨越多个层级传递引用

有时,您想要暴露的元素深埋在多个组件之中。您可以链式使用 forwardRef,让每个中间层都将收到的引用继续转发给下一层,直到引用最终落到目标 DOM 节点上。

链中的每个包装器自身都必须使用 forwardRef 并传递引用,因为中间的普通组件会切断连接。

forwardRef + memo 组合

forwardRef 和 React.memo 可以结合使用,同时实现引用转发和渲染记忆化。通常的顺序是 memo(forwardRef(Component)):用 memo 包装 forwardRef 的结果,以便记忆化比较仍然生效。

这种模式常见于注重性能的设计系统,其中频繁渲染的组件既必须暴露自身节点,又要跳过不必要的重新渲染。

在 DevTools 中查看 forwardRef

在 React DevTools 中,forwardRef 组件会显示为包裹在组件名称外部的 ForwardRef 标签。这样,您可以一眼确认组件是否参与了引用转发。

您可以为内部函数命名,或设置 displayName,使 DevTools 中的条目比通用的匿名 ForwardRef 标签更加清晰。

何时 NOT 使用 forwardRef

forwardRef 用于暴露 DOM 节点和命令式句柄,而不是传递数据。如果父组件需要影响子组件,请优先使用普通属性和状态,而不是通过引用深入访问。

过度使用引用会使组件紧密耦合并绕过 React 的数据流,从而让行为更难理解。只有在声明式属性确实无法表达这种交互时,才应使用 forwardRef。

现代 React 中的 forwardRef

forwardRef 仍然是组件库和可复用输入框暴露引用的标准工具。较新的 React 版本正逐步转向允许将 ref 作为普通属性传递,但 forwardRef 仍被广泛使用,也值得理解。

熟练掌握它,既能帮助您处理现有代码库,也能让您理解未来任何“将 ref 作为属性”语法所依赖的底层机制。

快速检查:forwardRef 的签名

测试您对 forwardRef 组件如何接收其引用的理解。

回顾:forwardRef

forwardRef 解决了父组件无法访问子组件 DOM 节点这一限制:它为组件提供第二个引用参数,组件可以将该引用转发到内部元素上。这样便能聚焦、测量和滚动子元素。

它可以与 memo 组合使用,也可以跨多个层级链式传递,并会在 DevTools 中显示为 ForwardRef。请将它用于命令式 DOM 访问,而不要用于传递数据;传递数据更适合使用属性。

常见问题解答

「forwardRef:向父组件暴露 DOM 引用」课时是免费的吗?

是的 — 「forwardRef:向父组件暴露 DOM 引用」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。

「forwardRef:向父组件暴露 DOM 引用」这节课中我会学到什么?

学习 forwardRef 如何让父组件访问子组件的 DOM 节点或组件实例。 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 React Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「forwardRef:向父组件暴露 DOM 引用」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 React Academy 课中编写并运行代码吗?

能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. forwardRef:向父组件暴露 DOM 引用
  2. useImperativeHandle:自定义实例值
  3. 构建命令式组件 API
  4. 何时使用命令式 API 与声明式 API
← 返回 React Academy