استخدام مكون وظيفي كعنصر فرعي لـ <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://github.com/nickluger/nextjs-link-ref-functional-comp-warning
يجب أن يعمل <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
بنفس الطريقة؟ أو ربما يتفاعل المبدعون مع اعتقادهم أن المطورين سيستخدمون وظيفة 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://github.com/zeit/next.js/issues/8962
لقد واجهت هذه المشكلة للتو عند ترقية 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} />)
}
للجزء الأمامي تذكر المستندات أيضًا 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>
حوله ، ولكنه سيؤدي إلى حدوث خطأ آخر مثل "must have href" ، وما إلى ذلك عند استخدام a11y وما شابه.
تحرير: قضى 15 مليونًا في محاولة اكتشاف ذلك ، إنه ممل جدًا ، ومضيعة للوقت ، ويبدو أنه يتصرف بشكل صحيح على الرغم من التحذير.
شخصيا ، الذهاب إلى https://github.com/zeit/next.js/issues/7915#issuecomment -511792629 أسهل بكثير.
ماذا عن هذا الحل باستخدام جزء رد الفعل
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} />
);
لا يؤدي هذا إلى إضافة أي غلاف HTML إضافي في الإخراج ( <div />
) ويجب ألا يؤدي إلى حدوث أي خطأ ذي صلة.
@ hill84 ممتع ، ولكن من أين يأتي myRef
في مثالك ؟
Vadorequest لقد أضفت المزيد من التفاصيل إلى تعليقي السابق.
كان اتباع اقتراح
""
زر const ButtonLink: FC
<
كان اتباع اقتراح
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>
فحص ، إنه يعمل!
لماذا هذا المرجع مطلوب حتى؟ هل هو ضمان الموضع الصحيح لـ href
في المكون المغلف الأساسي عند استخدام passHref
في <Link />
؟
هذا أمر مزعج للغاية نظرًا لأن المكون المخصص الخاص بي <a>
في الجذر ويمكنني أن أرى أنه يتم تطبيق href عليه بشكل صحيح على أي حال ... لديك مرساة في جذور وتجنب هذا كله ref
تصميم ديسيسيون.
React.forwardRef
شيء مرهق بشكل فظيع لإجبار الناس على التنفيذ ويلعب الجحيم مع الوبر الخاص بي 😞
أو على الأقل اجعلها ميزة اشتراك إذا كنت بحاجة إلى تحديد موضع href
في المكون الخاص بك. <Link href="/" passHref useRef />
؟
لا أعتقد أن الاضطرار إلى إنشاء وحدة أخرى لإعادة توجيه المرجع إلى مكون مخصص يعد حلاً جيدًا كما أنه متكرر للغاية.
الطريقة التي أستخدمها للتعامل مع هذه المشكلة هي تغليف المكون المخصص بعنصر 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 في ذلك اليوم وأنا أفكر في "Wow Next هو المستقبل". تعجبني حقًا Next ونظام Vercel البيئي وأريد أن أكون قادرًا بصدق على قول ذلك وأن أكون من المدافعين عن Next. ومع ذلك ، فإن إغلاق مثل هذه القضايا وعدم معالجتها يجعل من الصعب القيام بذلك. لقد رأيت هذا النوع من الأنماط عدة مرات خلال المشكلات هنا ، خاصةً مع جهاز التوجيه.
هناك 3 حلول لهذه المشكلة من جانب المستخدم ولا يوجد أي منها حل DX رائع.
React.forwardRef
. يمكن أن يكون هذا متكررًا جدًاdiv
، span
، a
، إلخ.router.push
بغض النظر عن الحل الذي تستخدمه ، فهي كلها غريبة وتتطلب تعليقات مرتبطة بهذه المشكلة أو المستندات لشرح لزملاء العمل / المساهمين سبب حاجتها لمنع الإزالة / التنظيف العرضي.
أعتقد أنه يجب إعادة فتح هذه القضية للمناقشة.
التعليق الأكثر فائدة
التفاف جميع المكونات الوظيفية المستخدمة داخل
Link
يدويًا ؟ ألا يجب أن يكون هناك حل أسهل وأقل تكرارا لهذا؟ ما لا يقل عن شيء مثل<Link href="/" forwardRef>...</Link>
؟