使用 asChild
属性将 Radix 的功能组合到其他元素类型或您自己的 React 组件上。
所有渲染 DOM 元素的 Radix 原始组件部分都接受 asChild
属性。当 asChild
设置为 true
时,Radix 将不会渲染默认的 DOM 元素,而是克隆该部分的子元素,并将使其功能正常运行所需的属性和行为传递给它。
在大多数情况下,您无需修改元素类型,因为 Radix 的设计旨在提供最合适的默认值。但是,在某些情况下,这样做会很有帮助。
一个很好的例子是 Tooltip.Trigger
。默认情况下,此部分渲染为 button
,但您可能还希望将工具提示添加到链接(a
标签)。让我们看看如何使用 asChild
来实现这一点
如果您确实决定更改底层元素类型,则您有责任确保其保持可访问性和功能性。例如,对于
Tooltip.Trigger
,它必须是可聚焦的元素,可以响应指针和键盘事件。如果您将其切换为div
,它将不再可访问。
实际上,您很少会像上面看到的那样修改底层 DOM 元素。相反,更常见的是使用您自己的 React 组件。对于大多数 Trigger
部分尤其如此,因为您通常希望将功能与设计系统中的自定义按钮和链接组合在一起。
这与上述工作原理完全相同,您将 asChild
传递给该部分,然后用您自己的组件将其包裹起来。但是,有一些需要注意的陷阱。
当 Radix 克隆您的组件时,它将传递自己的 props 和事件处理程序,使其具有功能性和可访问性。如果您的组件不支持这些 props,它将崩溃。
这是通过将所有 props 展开到底层 DOM 节点上来完成的。
我们建议始终这样做,这样您就不必担心实现细节(即,要接受哪些 props/事件)。我们发现这对于一般的“叶”组件来说是一个很好的实践。
与直接更改元素类型类似,您有责任确保自定义组件渲染的元素类型保持可访问性和功能性。
此外,Radix 有时需要将 ref
附加到您的组件(例如,为了测量其大小)。如果您的组件不接受 ref
,则它将崩溃。
这是使用 React.forwardRef
完成的(在 react.dev 上了解更多)。
虽然这对于所有部分来说不是必需的,但我们建议始终这样做,这样您就不必担心实现细节。 这对于叶组件来说通常也是一个好的做法。
asChild
可以根据您的需要进行深度使用。这意味着它是将多个原始组件的行为组合在一起的好方法。这是一个示例,说明如何将 Tooltip.Trigger
和 Dialog.Trigger
与您自己的按钮组合在一起