同样在这里。 如果使用这样的自定义组件,则会出错:
<Link href="/href">
<Button
type="custom"
color="#FCFCFC"
>
buttonText
</Button>
</Link>
仅在将组件用作子组件时才会发生这种情况。 这些不发出警告,例如:
<Link href="/href">
<button
type="custom"
color="#FCFCFC"
>
buttonText
</button>
</Link>
<Link href="/href">
<a>
<Button
type="custom"
color="#FCFCFC"
>
buttonText
</Button>
</a>
</Link>
有没有办法解决这个错误? 当我们确实希望利用某些功能(例如打字稿支持)时,我们将无法使用9。 只是注意到它升至9.0.3:/
您可以尝试暂时将其静音,例如:
// TODO: Muting error, fix as soon as zeit/next.js/issues/7915 resolved
const originalError = console.error;
console.error = (...args) => {
if (/Warning.*Function components cannot be given refs/.test(args[0])) {
return;
}
originalError.call(console, ...args);
};
我在这里有同样的问题。
如果您使用<Link/>
包装您的自定义组件,则可以像这样转发ref
:
const CustomComponent = React.forwardRef(function CustomComponent(props, ref) {
return (
<div/>
);
});
<Link href={"/"}>
<CustomComponent/>
</Link>
警告消失。
我已更新为9.0.4-canary.2
但在控制台上仍然收到警告。 我想念什么吗?
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 `Link`.
@ th0th您应该将组件包装在React.forwardRef
。 像这个:
import React from 'react'
import Link from 'next/link'
const CustomComponent = React.forwardRef((props, ref) => (
<a ref={ref} {...props}>
Click
</a>
))
export default () => (
<Link href='/' passHref>
<CustomComponent/>
</Link>
)
手动包装Link
使用的所有功能组件? 难道不应该有一个更简单,重复性更小的解决方案吗? 至少像<Link href="/" forwardRef>...</Link>
?
同意@nickluger,这似乎违反直觉。
是否所有其他库都应以相同方式实现forwardRef
属性? 或者,也许是有反应的创建者认为开发人员将使用React.forwardRef
函数而不是实现forwardRef
属性?
是的,同意@nickluger ,对Link
所有组件手动执行此操作很麻烦。
我们应该重新打开并重命名此问题(@ijjk),还是有人已经打开了一个新的问题?
同样在这里。 如果使用这样的自定义组件,则会出错:
<Link href="/href"> <Button type="custom" color="#FCFCFC" > buttonText </Button> </Link>
仅在将组件用作子组件时才会发生这种情况。 这些不发出警告,例如:
<Link href="/href"> <button type="custom" color="#FCFCFC" > buttonText </button> </Link> <Link href="/href"> <a> <Button type="custom" color="#FCFCFC" > buttonText </Button> </a> </Link>
这很可能会引发控制台错误:
Warning: validateDOMNesting(...): <a> cannot appear as a descendant of <a>.
我只是在升级Next JS时遇到了这个问题。 有没有解决的办法?
我不确定我是否了解如何使用forwardRef和包装我的组件。 我的button.js文件当前导出以下内容...。
const Button = (props) => {
return (<stuff />)
}
export default React.memo(Button)
见上文,我在这里打开了后续文件: https :
我只是在升级Next JS时遇到了这个问题。 有没有解决的办法?
我不确定我是否了解如何使用forwardRef和包装我的组件。 我的button.js文件当前导出以下内容...。
const Button = (props) => { return (<stuff />) } export default React.memo(Button)
在这种情况下,您应该能够
import {forwardRef} from 'react';
const Button = forwardRef(props, ref) => {
return (<stuff ref={ref} />)
}
对于forwardRef部分。 这些文档还提到了https://nextjs.org/docs#forcing -the-link-to-expose-href-to-its-child,尽管我没有尝试过。 我发现这样做
<Link
href={href}
>
<a>
{text}
</a>
</Link>
有效(尽管看起来很奇怪。)
在9.0.2中遇到此问题
使用<a></a>
可能有效,但在使用a11y和类似方法时会触发其他错误,例如“必须具有href”等。
编辑:花了1500万美元试图弄清楚这一点,这很无聊,很浪费时间,尽管有警告,但似乎仍能正常工作。
就个人而言, https: //github.com/zeit/next.js/issues/7915#issuecomment -511792629容易得多。
使用React片段作为轴承包装的解决方案呢?
import React, { Fragment, useRef } from 'react';
import { MyFunctionalComponent } from './my-functional-component';
const App = props => {
const myRef = useRef();
return (
<Link href={href}>
<Fragment>
<MyFunctionalComponent ref={myRef} />
</Fragment>
</Link>
);
}
其中<MyFunctionalComponent>
转发参考:
import React, { forwardRef } from 'react';
const MyFunctionalComponent = forwardRef(props, ref) => (
<div ref={ref} />
);
这不会在输出( <div />
)中添加任何其他HTML包装器,并且不会触发任何相关错误。
@ hill84有趣,但是在您的示例中myRef
来自哪里?
@Vadorequest我已在先前的评论中添加了更多详细信息。
遵循@ hill84的建议是一个不错的解决方法:
```
const ButtonLink:FC
<
遵循@ hill84的建议是一个不错的解决方法:
const ButtonLink: FC<ButtonLinkProps> = ({ children, href, ...props }) => ( <Link href={href}> <><Button link {...props}>{children}</Button></> </Link> );
我使用<><Component/></>
但链接无法操作。 我必须使用<div></div>
代替。
我建议一种解决方案,其中函数返回带有props而不是component的对象:
const propsUserBtn = user => ({
className: "h-10 w-10 font-black rounded-full bg-orange-200 text-teal-700",
title: user.first_name + ' ' + user.last_name,
children: (user.first_name.charAt(0) + user.last_name.charAt(0)).toUpperCase()
})
<Link href='/profile'>
<button { ...propsUserBtn(user) } />
</Link>
经检查,可以正常工作!
为什么甚至需要这个裁判? 难道是保证的正确位置href
在基础包组件时, passHref
在使用<Link />
?
这太烦人了,因为我的自定义<a>
,我可以看到它无论如何都正确地应用了href。我宁愿它强制您需要底层的自定义组件将锚定在根源,避免整个ref
设计需求。
React.forwardRef
是一件令人讨厌的事情,它迫使人们去实施,并且正在和我的短毛绒玩弄
或者,如果您需要在组件中指定href
的位置,则至少可以选择启用它。 <Link href="/" passHref useRef />
?
我认为不必创建另一个模块来将ref转发到自定义组件是一个很好的解决方案,并且它也很重复。
我用来处理此问题的方式是通过将自定义组件包装为div
元素(如@ namlq93所建议的
同样在这里。 如果使用这样的自定义组件,则会出错:
<Link href="/href"> <Button type="custom" color="#FCFCFC" > buttonText </Button> </Link>
仅在将组件用作子组件时才会发生这种情况。 这些不发出警告,例如:
<Link href="/href"> <button type="custom" color="#FCFCFC" > buttonText </button> </Link> <Link href="/href"> <a> <Button type="custom" color="#FCFCFC" > buttonText </Button> </a> </Link>
可行,谢谢队友!
遇到类似的问题
还在那儿
https://nextjs.org/docs/api-reference/next/link#if -the-child-is-a-function-component
这真是难过;这真是伤心。
前几天,我在观看NextJS会议时在想“哇,未来就是未来”。 我真的很喜欢Next和Vercel生态系统,我想坦白地说可以成为Next的拥护者。 但是,像这样的问题由于无法解决而无法解决。 在这里的所有问题中,我已经多次看到这种模式,特别是在路由器方面。
从用户方面有3种解决方案,它们都不是出色的DX。
React.forwardRef
。 这可能是非常重复的div
, span
, a
等标签中。router.push
无论您使用哪种解决方案,它们都很奇怪,需要链接到此问题或文档的注释来向同事/贡献者解释为什么需要这种方法来防止意外删除/清除。
我认为这个问题应该重新讨论。
最有用的评论
手动包装
Link
使用的所有功能组件? 难道不应该有一个更简单,重复性更小的解决方案吗? 至少像<Link href="/" forwardRef>...</Link>
?