機能コンポーネントを<Link/>
子として使用すると、次の原因になります。
Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
これは、v8 => v9からアップグレードした後にのみ発生しました。
複製リポジトリ: https :
<Link/>
は、機能コンポーネントでも機能するはずです/警告を表示しません。
こっちも一緒。 次のようなカスタムコンポーネントを使用すると、エラーが発生します。
<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
属性を実装する必要がありますか? あるいは、開発者がforwardRef
属性を実装する代わりにReact.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などを使用すると、「musthavehref」などの他のエラーがトリガーされます。
編集:これを理解するために15分を費やしました、それは非常に退屈で、そのような時間の無駄であり、警告にもかかわらず適切に動作するようです。
個人的には、 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>
を使用する必要があります。
関数がコンポーネントではなく小道具を使用してオブジェクトを返すソリューションを提案します。
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>
チェックして、動作します!
なぜこの参照が必要なのですか? passHref
が<Link />
使用されている場合、基になるラップされたコンポーネントでのhref
の正しい配置を保証するためですか?
私のカスタムコンポーネントのルートに<a>
があり、とにかくhrefが正しく適用されていることがわかるので、これは非常に面倒です...むしろ、基になるカスタムコンポーネントが必要であることを強制したいと思います。ルートにアンカーを配置し、このref
デザイン全体の乾燥を回避します。
React.forwardRef
は、人々に実装を強制するのは恐ろしく面倒なことであり、私のリンターと地獄で遊んでいます😞
または、コンポーネント内のhref
の配置を指定する必要がある場合は、少なくともオプトイン機能にする必要があります。 <Link href="/" passHref useRef />
?
参照をカスタムコンポーネントに転送するために別のモジュールを作成する必要があることは良い解決策ではなく、繰り返しが多すぎると思います。
私がこの問題を処理するために使用している方法は、 @ namlq93によって提案されているようにカスタムコンポーネントをdiv
要素でラップすること
こっちも一緒。 次のようなカスタムコンポーネントを使用すると、エラーが発生します。
<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
これは悲しいです。
先日、「Wow Next isthefuture」と思ってNextJSカンファレンスを見ていました。 私はNextとVercelエコシステムが本当に好きで、正直に言ってNextの支持者になりたいと思っています。 ただし、このような問題は解決されておらず、対処されていないため、そうすることは困難です。 私はここでの問題を通して、特にルーターで、このタイプのパターンを何度も見ました。
この問題にはユーザー側から3つの解決策があり、どれも優れたDXではありません。
React.forwardRef
でラップします。 これは非常に繰り返しになる可能性がありますdiv
、 span
、 a
などのタグでラップします。router.push
を使用しますどのソリューションを使用しても、それらはすべて奇妙であり、偶発的な削除/クリーンアップを防ぐ必要がある理由を同僚/寄稿者に説明するために、この問題またはドキュメントにリンクするコメントが必要です。
この問題は議論のために再開されるべきだと思います。
最も参考になるコメント
Link
内で使用されるすべての機能コンポーネントを手動でラップしますか? これに対して、より簡単で繰り返しの少ない解決策があるべきではありませんか? 少なくとも<Link href="/" forwardRef>...</Link>
ようなもの?