反应propTypes组件类?

时间:2017-07-26 01:23:23

标签: reactjs

如何验证提供的prop是组件类(而不是实例)?

e.g。

export default class TimelineWithPicker extends React.PureComponent {

    static propTypes = {
        component: PropTypes.any, // <-- how can I validate that this is a component class (or stateless functional component)?
    };

    render() {
        return (
            <this.props.component {...this.props} start={this.state.start}/>
        );
    }
}

2 个答案:

答案 0 :(得分:24)

已编辑:已将React的FancyButton示例添加到codesandbox以及自定义道具检查功能,该功能与React 16.3中的新React.forwardRef api一起使用。 React.forwardRef api返回一个具有render函数的对象。我正在使用以下自定义道具检查器来验证此道具类型。 - 感谢Ivan Samovar注意到这种需求。

FancyButton: function (props, propName, componentName) {
  if(!props[propName] || typeof(props[propName].render) != 'function') {
    return new Error(`${propName}.render must be a function!`);
  }
}

您需要使用 PropTypes.element 。实际上...... PropType.func适用于无状态功能组件和类组件。

我已经制作了一个沙箱来证明这是有效的...想到这是需要的,因为我首先给了你错误的信息。非常抱歉!

工作sandbox example

以下是链接失效时的测试代码:

import React from 'react';
import { render } from 'react-dom';
import PropTypes from "prop-types";

class ClassComponent extends React.Component {
  render() {
    return <p>I'm a class component</p>
  }
}

const FancyButton = React.forwardRef((props, ref) => (
  <button ref={ref} className="FancyButton">
    {props.children}
  </button>
));

// You can now get a ref directly to the DOM button:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;

const FSComponent = () => (
    <p>I'm a functional stateless component</p>
);

const Test = ({ ClassComponent, FSComponent, FancyButton }) => (
  <div>
    <ClassComponent />
    <FSComponent />
    <FancyButton />
  </div>
);
Test.propTypes = {
  ClassComponent: PropTypes.func.isRequired,
  FSComponent: PropTypes.func.isRequired,
  FancyButton: function (props, propName, componentName) {
    if(!props[propName] || typeof(props[propName].render) != 'function') {
      return new Error(`${propName}.render must be a function!`);
    }
  },
}

render(<Test
         ClassComponent={ ClassComponent }
         FSComponent={ FSComponent }
         FancyButton={ FancyButton } />, document.getElementById('root'));

答案 1 :(得分:1)

对于使用PropTypes >= 15.7.0的任何人,此pull request中都添加了一个新的PropTypes.elementType,并已在february 10, 2019上发布。

此prop类型支持所有组件(本机组件,无状态组件,有状态组件,前向引用React.forwardRef,上下文提供者/消费者)。

当所有这些元素都不是时,它会发出警告;当传递的prop是元素(PropTypes.element)而不是类型时,它也会发出警告。

最后,您可以像使用其他道具类型一样使用它:

const propTypes = {
    component: PropTypes.elementType,
    requiredComponent: PropTypes.elementType.isRequired,
};