You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js组件遇ForwardRef警告,React.forwardRef无效如何解决?

问题:Next.js AppBarContent组件的ref警告问题

组件代码

const AppBarContent = (props: Props) => {
    // ** Props
    const {
        horizontalAppBarContent: userHorizontalAppBarContent,
        horizontalAppBarBranding: userHorizontalAppBarBranding,
    } = props

    // ** Hooks
    const theme = useTheme()

    return (
        <div
            style={{
                width: '100%',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'space-between',
            }}
        >
            {userHorizontalAppBarBranding ? (
                userHorizontalAppBarBranding(props)
            ) : (
                <Link href="/">
                    <Image src={'/images/logo.svg'} width={48} height={48} />
                </Link>
            )}

警告信息

next-dev.js?3515:25 Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()? Check the render method of ForwardRef.

尝试操作与疑问

  • 按提示用const AppBarContent = React.forwardRef((props: Props, ref) => {})包裹组件后,警告仍存在;
  • 在<Link>和<Image>之间添加<a>标签后,警告消失,但认为这是不符合Next.js文档的临时方案;
  • 想了解正确解决方法,以及为何React.forwardRef无效。

调用代码片段

return (
    <HorizontalLayoutWrapper className="layout-wrapper">
        {/* Navbar (or AppBar) and Navigation Menu Wrapper */}
        <AppBar
            color="default"
            elevation={skin === 'bordered' ? 0 : 3}
            className="layout-navbar-and-nav-container"
            position={appBar === 'fixed' ? 'sticky' : 'static'}
            
        >
            {/* Navbar / AppBar */}
            <div className="layout-navbar">
                <div className="navbar-content-container">
                    <AppBarContent
解决方案

为什么React.forwardRef无效?

警告的根源不在AppBarContent组件本身,而是Next.js的<Link>组件会尝试给直接子组件传递ref,但Next.js的<Image>是函数式组件,默认无法接收ref。你给AppBarContent添加forwardRef,但问题出在组件内部的<Link>与<Image>的组合逻辑上,所以无法解决警告。

正确解决方法

以下两种方式均符合Next.js官方规范:

方式1:给Link添加passHref,并让Image能接收ref

Next.js的<Link>默认不会将href传递给非原生<a>标签的子组件,需通过passHref开启该行为;同时要确保子组件能接收ref,可通过React.forwardRef包装<Image>:

// 先包装Image,使其能接收ref
const ForwardedImage = React.forwardRef((props, ref) => (
  <Image ref={ref} {...props} />
));

// 在AppBarContent中使用
<Link href="/" passHref>
  <ForwardedImage src="/images/logo.svg" width={48} height={48} />
</Link>

如果不需要Next.js <Image>的优化特性,也可以直接使用原生<img>标签:

<Link href="/" passHref>
  <img src="/images/logo.svg" width={48} height={48} />
</Link>

方式2:Link包裹原生a标签(合规方案)

你之前添加<a>标签的思路是正确的,只要给<Link>加上passHref,这种方式完全符合Next.js文档规范,并非临时方案:

<Link href="/" passHref>
  <a>
    <Image src="/images/logo.svg" width={48} height={48} />
  </a>
</Link>

原生<a>标签可以直接接收<Link>传递的ref,因此不会触发警告。

内容的提问来源于stack exchange,提问作者János

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 21:05:14