Предупреждение material-ui v4.0.1 «Ожидается элемент, который может содержать ссылку»

Я обновился до material-ui v4.0.1 и вижу, что модальные окна теперь требуют переадресованной ссылки. У меня возникли проблемы с реализацией исправления для этого с использованием компонентов класса и диалогов.

Я пытался использовать React.createRef(), а также React.forwardRef((props, ref) => (...) в нескольких местах, но не могу понять, как устранить это предупреждение.

В моем родительском компоненте я визуализирую пользовательский компонент

<ApolloFormDialog />

В ApolloFormDialog я визуализирую по существу:

<Dialog ...>
  {title}
  {subtitle}
  {form}
</Dialog>

Полное предупреждение Warning: Failed prop type: Invalid prop 'children' supplied to 'Modal'. Expected an element that can hold a ref. Did you accidentally use a plain function component for an element instead?

Однако в настоящее время я использую компоненты класса. Переход на использование функциональных компонентов сейчас невозможен, так как мое приложение довольно большое.


Я попытался добавить ссылку на ApolloFormDialog как

<ApolloFormDialog ref = {React.createRef()} />

а также обернуть класс ApolloFormDialog с помощью:

export default React.forwardRef((props, ref) => <ApolloFormDialog ref = {ref} {...props}/>)

а затем добавить это ref в диалоговое окно как

<Dialog ref = {this.props.ref} />

но предупреждение все еще сохраняется, и я не уверен, куда идти дальше.

Пожалуйста, создайте КодПесочница, который воспроизводит эту проблему. Ничто в версии 4 не заставит вас преобразовывать компоненты класса в компоненты функций. В предупреждении говорится, что children из Modal являются проблемой, однако Dialog контролирует дочерние элементы, переданные Modal, поэтому было бы полезно увидеть воспроизведение проблемы, чтобы полностью диагностировать, что происходит.

Ryan Cogswell 28.05.2019 21:14

Спасибо за предложение, @RyanCogswell. Я добавил свой код в CodePen и не смог его воспроизвести, что меня расстроило, поэтому оттуда я начал удалять реквизиты в своем диалоговом окне, пока он не оказался в том же состоянии, что и пример CodePen, и оказалось, что после удаления реквизита TransitionComponent, предупреждение ушло. Я не уверен, является ли это ошибкой в ​​v4, но, возможно, стоит создать проблему, если я смогу воспроизвести проблему с этой опорой в CodePen.

Lief 28.05.2019 21:49
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
16
2
11 377
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Моя проблема на самом деле была связана не с Dialog, а с опорой TransitionComponent на Dialog.

Я переключаюсь между двумя типами переходов в моем ApolloFormDialog в зависимости от того, находится ли экран ниже определенной точки останова, которая вызывалась как функциональные компоненты:

<Dialog
  open = {open}
  onClose = {onRequestClose}
  classes = {{
    paper: classnames(classes.dialogWidth, classes.overflowVisible),
  }}
  fullScreen = {fullScreen}
  TransitionComponent = {
    fullScreen ? FullscreenTransition : DefaultTransition
  }
>
  {content}
</Dialog>

FullscreenTransition и DefaultTransition берутся из файла и определяются следующим образом:

import React from 'react'
import Fade from '@material-ui/core/Fade'
import Slide from '@material-ui/core/Slide'

export function DefaultTransition(props) {
  return <Fade {...props} />
}

export function FullscreenTransition(props) {
  return <Slide direction='left' {...props} />
}

export function FullscreenExpansion(props) {
  return <Slide direction='right' {...props} />
}

Изменение этих функций на следующие исправило мою проблему:

import React from 'react'
import Fade from '@material-ui/core/Fade'
import Slide from '@material-ui/core/Slide'

export const DefaultTransition = React.forwardRef((props, ref) => (
  <Fade {...props} ref = {ref} />
))

export const FullscreenTransition = React.forwardRef((props, ref) => (
  <Slide direction='left' {...props} ref = {ref} />
))

export const FullscreenExpansion = React.forwardRef((props, ref) => (
  <Slide direction='right' {...props} ref = {ref} />
))


С моей стороны это было относительно сложно решить, поэтому я оставлю этот вопрос на тот случай, если кто-то еще столкнется с подобной проблемой где-нибудь в будущем.

В качестве альтернативы вы также можете создать из него класс и компонент без состояния, и это решит его (машинопись не любит приведенное выше решение)

Petrogad 01.08.2019 19:27

React.forwardRef решает проблему и для меня.

Чтобы убедиться, что решение React.forwardRef работает с Typescript, вы должны реализовать следующее в соответствии с документацией в Material-UI:

const Transition = React.forwardRef<unknown, TransitionProps>(function Transition(props, ref) {
  return <Slide ref = {ref} {...props} />;
});

См. исходный код в их демо здесь.

Да, forwarRef исправил это и для меня при работе с модальными компонентами Material UI. const SomeModal = React.forwardRef (функция Modal ({orgInfo, handleClose}, ref) {...})

Davis Jones 07.04.2020 00:06

У меня была такая же проблема с "@material-ui/core/Tooltip", обертывающим новый функциональный компонент. Даже если компонент был завернут в div внутри собственного кода.

<!-- "Did you accidentally use a plain function component for an element instead?" -->

<Tooltip>
  <NewFunctionalComponent />
</Tooltip>

<!-- Wrapped in a new div, devtools won't QQ any more -->

<Tooltip>
  <div>
    <NewFunctionalComponent />
  </div>
</Tooltip>

<!-- No more warnings! -->

+1! Я также использовал Tooltip, когда столкнулся с этой проблемой. React.forwardRef() мне не помогло. Это устранит предупреждение, но не покажет Tooltip. Однако это решение сработало.

Akaisteph7 13.07.2021 22:02

Перенос моего компонента в другой div внутри компонента перехода material-ui (например, Slide, Fade и т. д.) решает мою проблему. Пример кода:

От

<Slide direction='Right' in = {isSideNavOpen} mountOnEnter unmountOnExit>
      <MyComponent />
</Slide>

К

<Slide direction='Right' in = {isSideNavOpen} mountOnEnter unmountOnExit>
     <div><MyComponent /></div>
</Slide>`

Другие вопросы по теме