material-ui v4.0.1警告“预期可以容纳引用的元素”

Lie*_*ief 6 reactjs material-ui

我升级到material-ui v4.0.1,发现Modals现在需要转发的参考。我在使用类组件和对话框为此实现修复时遇到一些麻烦。

我在几个地方都尝试过使用React.createRef()React.forwardRef((props, ref) => (...)但是我不知道如何解决此警告。

在我的父组件中,我渲染了一个自定义组件

<ApolloFormDialog />
Run Code Online (Sandbox Code Playgroud)

ApolloFormDialog本质上,我渲染:

<Dialog ...>
  {title}
  {subtitle}
  {form}
</Dialog>
Run Code Online (Sandbox Code Playgroud)

完整的警告是 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()} />
Run Code Online (Sandbox Code Playgroud)

以及将ApolloFormDialog的类包装为:

export default React.forwardRef((props, ref) => <ApolloFormDialog ref={ref} {...props}/>)
Run Code Online (Sandbox Code Playgroud)

然后将其添加ref到对话框中

<Dialog ref={this.props.ref} />
Run Code Online (Sandbox Code Playgroud)

但是警告仍然存在,而且我不确定从这里到哪里去。

Lie*_*ief 14

我的问题实际上与无关Dialog,但与提案TransitionComponent有关Dialog

ApolloFormDialog根据屏幕是否在某个断点以下而在两种过渡类型之间进行切换,这被称为功能组件:

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

FullscreenTransitionDefaultTransition来自文件,其定义如下:

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} />
}

Run Code Online (Sandbox Code Playgroud)

将这些功能更改为以下内容可以解决我的问题:

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} />
))

Run Code Online (Sandbox Code Playgroud)

从我的角度来看,这是一个相对较难解决的问题,因此,我打算不提这个问题,以防万一有人在路上遇到类似的问题。


小智 11

将我的组件包装到 Material-ui 过渡组件(如 Slide、Fade 等)内的另一个 div 解决了我的问题。示例代码:

<Slide direction='Right' in = {isSideNavOpen} mountOnEnter unmountOnExit>
      <MyComponent />
</Slide>
Run Code Online (Sandbox Code Playgroud)

<Slide direction='Right' in = {isSideNavOpen} mountOnEnter unmountOnExit>
     <div><MyComponent /></div>
</Slide>`
Run Code Online (Sandbox Code Playgroud)


Tho*_*ann 7

我在“@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! -->
Run Code Online (Sandbox Code Playgroud)

  • +1!当我遇到这个问题时,也在使用“Tooltip”。`React.forwardRef()` 对我不起作用。它将消除警告,但不会显示“工具提示”。然而这个解决方案有效。 (2认同)
  • 包装盒对我有用!谢谢 :) (2认同)

Pac*_*ost 6

React.forwardRef 也为我解决了这个问题。

为确保该React.forwardRef解决方案适用于 Typescript,您必须按照 Material-UI 中的文档实现以下内容:

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

此处查看他们演示中的源代码。