Использование функционального компонента в качестве дочернего для <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} />)
}
для части 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>
around может работать, но вызовет другую ошибку, например "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 Я добавил подробности в свой предыдущий комментарий.
После предложения @ 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>
Проверил, работает!
Зачем вообще нужен этот реф? Гарантирует ли это правильное размещение 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 и думал: «Вау, следующее - будущее». Мне очень нравится Next и экосистема Vercel, и я хочу, честно говоря, иметь возможность сказать это и быть сторонником Next. Однако из-за того, что подобные проблемы закрыты и не решены, сделать это сложно. Я встречал этот тип шаблона несколько раз в описанных здесь проблемах, особенно с маршрутизатором.
Со стороны пользователя есть 3 решения этой проблемы, и ни одно из них не является отличным DX.
React.forwardRef
. Это может быть очень повторяющимсяdiv
, span
, a
и т. Д.router.push
Независимо от того, какое решение вы используете, они все странные и требуют комментариев, связанных с этой проблемой, или документов, чтобы объяснить коллегам / участникам, почему это необходимо для предотвращения случайного удаления / очистки.
Думаю, этот вопрос следует снова открыть для обсуждения.
Самый полезный комментарий
Обернуть все используемые функциональные компоненты в
Link
вручную ? Разве для этого не должно быть более простого и менее повторяющегося решения? Хоть что-то вроде<Link href="/" forwardRef>...</Link>
?