У меня есть следующее (используя Material UI)....
import React from "react";
import { NavLink } from "react-router-dom";
import Tabs from "@material-ui/core/Tabs";
import Tab from "@material-ui/core/Tab";
function LinkTab(link){
return <Tab component = {NavLink}
to = {link.link}
label = {link.label}
value = {link.link}
key = {link.link}
/>;
}
В новых версиях это вызывает следующее предупреждение...
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. in NavLink (created by ForwardRef)
Пробовал менять на...
function LinkTab(link){
// See https://material-ui.com/guides/composition/#caveat-with-refs
const MyLink = React.forwardRef((props, ref) => <NavLink {...props} ref = {ref} />);
return <Tab component = {MyLink}
to = {link.link}
label = {link.label}
value = {link.link}
key = {link.link}
/>;
}
Но я все еще получаю предупреждение. Как решить эту проблему?





NavLink from react-router — это функциональный компонент, представляющий собой специализированную версию Связь, которая предоставляет для этой цели свойство innerRef.
// required for react-router-dom < 6.0.0
// see https://github.com/ReactTraining/react-router/issues/6056#issuecomment-435524678
const MyLink = React.forwardRef((props, ref) => <NavLink innerRef = {ref} {...props} />);
Вы также могли бы поискать в наших документах react-router, что приведет вас к https://mui.com/getting-started/faq/#how-do-i-use-react-router, который ссылается на https://mui.com/components/buttons/# третья сторона-маршрутизация-библиотека. В последней ссылке приведен рабочий пример, а также объясняется, как это может измениться в react-router v6.
как насчет того, если вы вообще не используете реактивный маршрутизатор? как вы используете forwardRef с тем же предупреждением?
эта ссылка поможет мне решить проблему [blog.jscrambler.com/…
Вы можете использовать судьи вместо ссылка. Это работает только потому, что избегает специального имени пропса ссылка.
<InputText
label = "Phone Number"
name = "phoneNumber"
refs = {register({ required: true })}
error = {errors.phoneNumber ? true : false}
icon = {MailIcon}
/>
Привет. Не могли бы вы объяснить разницу между ref и refs? Я просмотрел документацию React, но не смог найти ссылки на refs = {} (множественное число). Это действительно сработало для меня, но я хотел бы понять, как это работает с функциональными компонентами. Спасибо.
Дело не в том, что это конкретно реф. Просто проп "ref" особенный (так же, как и "key"). Вы можете передать его как «foo» вместо «refs», и это тоже сработает.
Как сказал @FilipeValente, это не какая-то конкретная ссылка. Он просто выступает в качестве реквизита,
Я также обнаружил, что задаюсь вопросом, был ли refs каким-то особым реквизитом, поэтому я выбрал innerRef только потому, что это немного яснее в отношении того, что он делает.
Просто поставьте как innerRef,
// Client.js
<Input innerRef = {inputRef} />
Используйте его как ref.
// Input.js
const Input = ({ innerRef }) => {
return (
<div>
<input ref = {innerRef} />
</div>
)
}
Как бы это ни было просто - я обнаружил, что это легче всего обернуть в голове.
@ Хасан серьезно? Это действительно сработало и не привело к каким-либо существенным изменениям, как упоминалось в других ответах.
Если это работает, почему существует forwardRef?
Волшебство! Так же просто, как изменить его с ref на innerRef
const renderItem = ({ item, index }) => {
return (
<>
<Item
key = {item.Id}
item = {item}
index = {index}
/>
</>
);
};
Использовать фрагмент для решения React.forwardRef()? предупреждение
Если вы обнаружите, что не можете добавить к компоненту пользовательскую опору ref или forwardRef, у меня есть хитрость, позволяющая получить объект ref для вашего функционального компонента.
Предположим, вы хотите добавить ссылку на пользовательский функциональный компонент, например:
const ref = useRef();
//throws error as Button is a functional component without ref prop
return <Button ref = {ref}>Hi</Button>;
Вы можете обернуть его в общий элемент html и установить на нем ref.
const ref = useRef();
// This ref works. To get button html element inside div, you can do
const buttonRef = ref.current && ref.current.children[0];
return (
<div ref = {ref}>
<Button>Hi</Button>
</div>
);
Конечно, управляйте состоянием соответственно и тем, где вы хотите использовать объект buttonRef.
Одно предложение по объявлению переменной buttonRef может быть более кратким, чтобы использовать необязательную цепочку: const buttonRef = ref.current?.children[0];
чтобы исправить это предупреждение, вы должны обернуть свой пользовательский компонент функцией forwardRef, как очень хорошо упомянуто в этом блог.
const AppTextField =(props) {return(/*your component*/)}
измените следующий код на
const AppTextField = forwardRef((props,ref) {return(/*your component*/)}
В нашем случае мы передавали компонент SVG (логотип сайта) непосредственно в Компонент ссылки NextJS, который был немного настроен, и мы получали такую ошибку.
Компонент заголовка, в котором использовался SVG, который «вызывал» проблему.
import Logo from '_public/logos/logo.svg'
import Link from '_components/link/Link'
const Header = () => (
<div className = {s.headerLogo}>
<Link href = {'/'}>
<Logo />
</Link>
</div>
)
Сообщение об ошибке на консоли
Function components cannot be given refs. Attempts to access this ref will fail.
Did you mean to use React.forwardRef()?
Индивидуальный компонент ссылки
import NextLink from 'next/link'
import { forwardRef } from 'react'
const Link = ({ href, shallow, replace, children, passHref, className }, ref) => {
return href ? (
<NextLink
href = {href}
passHref = {passHref}
scroll = {false}
shallow = {shallow}
replace = {replace}
prefetch = {false}
className = {className}
>
{children}
</NextLink>
) : (
<div className = {className}>{children}</div>
)
}
export default forwardRef(Link)
Теперь мы убедились, что используем forwardRef в нашем настроенном компоненте ссылки, но мы все равно получили эту ошибку.
Чтобы решить эту проблему, я изменил позиционирование обертки элемента SVG на это и пуф:
const Header = () => (
<Link href = {'/'}>
<div className = {s.headerLogo}>
<Logo />
</div>
</Link>
)
Была аналогичная проблема с созданием пользовательского компонента следующей ссылки, который в основном представляет собой оболочку вокруг стилизованного текстового компонента - решил ее, добавив фрагмент вокруг моего обернутого компонента вместо div.
Я просто вставляю сюда skychavda решение, так как оно предоставляет ссылку на дочерний элемент: так что вы можете напрямую вызывать дочерний метод или дочернюю ссылку из родителя без каких-либо предупреждений.
источник: https://github.com/reactjs/reactjs.org/issues/2120
/* Child.jsx */
import React from 'react'
class Child extends React.Component {
componentDidMount() {
const { childRef } = this.props;
childRef(this);
}
componentWillUnmount() {
const { childRef } = this.props;
childRef(undefined);
}
alertMessage() {
window.alert('called from parent component');
}
render() {
return <h1>Hello World!</h1>
}
}
export default Child;
/* Parent.jsx */
import React from 'react';
import Child from './Child';
class Parent extends React.Component {
onClick = () => {
this.child.alertMessage(); // do stuff
}
render() {
return (
<div>
<Child childRef = {ref => (this.child = ref)} />
<button onClick = {this.onClick}>Child.alertMessage()</button>
</div>
);
}
}
Как насчет того, когда у нас есть хэш-ссылка от react-router-hash-link?