材料-UI v4.0.1 警告"Expected an element that can hold a ref"



我升级到 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} />

但警告仍然存在,我不确定从这里开始。

我在包装新功能组件时遇到了同样的问题"@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 complain anymore -->
<Tooltip>
  <div>
    <NewFunctionalComponent />
  </div>
</Tooltip>
<!-- No more warnings! -->

我的问题实际上与Dialog有关,但与Dialog上的道具TransitionComponent有关。

我在ApolloFormDialog中的两种类型的过渡之间切换,具体取决于屏幕是否低于某个断点,该断点被称为函数组件:

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

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

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

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

对我来说,这是一个相对难以解决的问题,所以我将把这个问题留在那里,以防其他人在路上遇到类似的问题。

将我的组件包装到材料-UI 过渡组件(如幻灯片、淡入淡出等(中的另一个div 解决了我的问题。示例代码:

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

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

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

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

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

在此处查看其演示中的源代码。

我遇到了同样的错误

预期 CAND 持有引用的元素

我通过在我的孩子组件周围添加一个<Box></Box>来解决。

<Modal open={open} onClose={handleClose}>
    <DetailsCard />
</Modal>

<Modal open={open} onClose={handleClose}>
  <Box>
    <DetailsCard />
  </Box>
</Modal>

我有一个类似的问题,我通过将我的功能组件包装在div 中来解决它。就我而言,问题与工具提示组件包装自定义功能组件有关。

<Tooltip tittle={...}>
       <CustomFC />
</Tooltip>

解决方案是

<Tooltip tittle={...}>
    <div>
       <CustomFC />
    </div>
</Tooltip>

相关内容

最新更新