如何用Headless UI DataInteractive包裹next-intl Link替代Next.js Link
问题分析
这个错误的核心原因是:Headless UI 的 DataInteractive 需要将交互相关的 props(比如 ref、onFocus、data-headlessui-state 等)传递给真实的 DOM 元素,但 next-intl 的 IntlLink 默认内部结构没有让这些外部 props 正确转发到 <a> 标签上,导致 DataInteractive 尝试把 props 传递给了 Fragment,触发报错。
解决方案
方案1:指定 IntlLink 渲染原生 <a> 标签
给 IntlLink 添加 component="a" 属性,强制它渲染原生 <a> 元素,这样 DataInteractive 就能把所有必要的 props 转发到这个真实 DOM 节点上:
import * as Headless from '@headlessui/react' import { Link as IntlLink, type LinkProps as IntlLinkProps } from '../i18n/routing'; import React, { forwardRef } from 'react' export const Link = forwardRef(function Link( props: IntlLinkProps & React.ComponentPropsWithoutRef<'a'>, ref: React.ForwardedRef<HTMLAnchorElement> ) { return ( <Headless.DataInteractive> <IntlLink {...props} ref={ref} component="a" /> </Headless.DataInteractive> ) })
方案2:手动包裹原生 <a> 标签作为子元素
如果方案1不生效,可以通过 IntlLink 的子元素模式,手动渲染 <a> 标签,让 DataInteractive 直接把 props 传递给这个标签:
import * as Headless from '@headlessui/react' import { Link as IntlLink, type LinkProps as IntlLinkProps } from '../i18n/routing'; import React, { forwardRef } from 'react' export const Link = forwardRef(function Link( props: IntlLinkProps & React.ComponentPropsWithoutRef<'a'>, ref: React.ForwardedRef<HTMLAnchorElement> ) { const { href, ...restProps } = props; return ( <Headless.DataInteractive> <IntlLink href={href}> <a ref={ref} {...restProps} /> </IntlLink> </Headless.DataInteractive> ) })
类型兼容说明
注意把原有的 next/link 的 LinkProps 替换成 next-intl 导出的 LinkProps(重命名为 IntlLinkProps 避免冲突),这样能确保所有 props 类型匹配,避免 TypeScript 报错。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

