Я обновился до 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} />

Но предупреждение все еще сохраняется, и я не уверен, куда идти отсюда.

6
Lief 28 Май 2019 в 21:07

2 ответа

Лучший ответ

Моя проблема на самом деле не связана с 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} />
))


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

19
Lief 28 Май 2019 в 20:06

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

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

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

Посмотрите исходный код в их демонстрации здесь.

3
PacificFrost 12 Сен 2019 в 17:14