迁移到material-ui v4,我收到有关模态组件的警告

时间:2019-09-06 08:03:19

标签: reactjs material-ui

material-ui升级到v4以来,我收到了有关Modal组件的一些警告。

例如

Failed prop type: Invalid prop children supplied to ForwardRef(Modal).

Function components cannot be given refs.

这是模态代码(警告1):

import React from 'react';
import Proptypes from 'prop-types';
...

class DetailDialog extends React.Component {
  render() {
    const { classes, open, onClose } = this.props;

    return (
      <Dialog
        open={open}
      >
        ...
      </Dialog>
    );
  }
}

DetailDialog.propTypes = {
  open: Proptypes.bool,
  onClose: Proptypes.func,
};

export default DetailDialog;

这是模态代码(警告2):

import React from 'react';
import PropTypes from 'prop-types';
...

class SelectCatDialog extends React.Component {
  render() {
    const { open, list, onClose } = this.props;

    return (
      <Dialog
        open={open}
        onClose={onClose}
      >
        ...
      </Dialog>
    )
  }
}

SelectCatDialog.propTypes = {
  open: PropTypes.bool,
  onClose: PropTypes.func,
}

SelectCatDialog.defaultProps = {
  list: [],
}

export default SelectCatDialog;

这是调用模式页面代码:

import React from 'react';
import DetailDialog from './components/DetailDialog';
import SelectProcDialog from './components/SelectProcDialog';

class Index extends React.Component {
  render() {
    return (
      ...
        <DetailDialog
          open={this.state.detailDialog}
          entity={this.state.currentDetail}
          onClose={this.handleDetailClose.bind(this)}
        />

        <SelectProcDialog
          open={this.state.catalogDialog}
          list={this.props.catalog}
          onOk={(value) => this.handleSelectCatalogOk(value)}
          onClose={() => this.setState({ catalogDialog: false })}
        />
      ...
    )
  }
}

export default Index;

发生了什么事?在v3版本中工作正常。有人可以回答吗?

2 个答案:

答案 0 :(得分:2)

从 Material-UI v3 迁移到 v4 后,我刚刚遇到了完全相同的问题。

我完全同意接受的答案,不过,我在这里发布了另一种方法,以防有人宁愿继续使用功能组件(就像我一样)。

功能组件不能按原样保存 ref

因此,向子组件提供 ref 的方式实际上是转发它。

React 文档对此进行了很好的解释 example,ReactJS Github 上的 issue 对此进行了详细说明。

所以基本上,这里可以做的是:

const Transition = React.forwardRef((props, ref) => (
  <Slide direction="up" {...props} ref={ref} />
));

能够通过 Transition 组件将引用转发到 Slide 组件。

打字稿方式

⚠️ 请注意,如果在 Typescript 项目中使用,之前的代码会抛出 TS2322 错误。

此 Material-UI Github issue 中描述并解决了此错误。

因此,在 Typescript 项目中,将功能组件用作 Material-UI v4 Transition 组件的 Dialog 组件的最佳方法 (imho) 如下:

import { SlideProps } from '@material-ui/core/Slide';

const Transition = React.forwardRef<unknown, SlideProps>((props, ref) => (
    <Slide direction="up" {...props} ref={ref} />
));

上面的代码修复了两个错误:

  • Failed prop type: Invalid prop children supplied to ForwardRef(Modal).
  • [TypeScript] Error: TransitionComponent type not assignable to 'ForwardRefExoticComponent'

答案 1 :(得分:1)

从V4开始,Dialog和Modal子代必须能够保留引用。
以下内容可以保存参考:

  
      
  • 任何Material-UI组件
  •   
  • 类组件,即React.Component或React.PureComponent
  •   
  • DOM(或主机)组件,例如div或按钮
  •   
  • React.forwardRef组件
  •   
  • React.lazy组件
  •   
  • React.memo组件
  •   

该错误声明您将功能组件作为模态的子代提供。
要解决该错误,请将功能组件更改为可以容纳ref的组件(例如类组件)。