简体   繁体   English

反应 propTypes 组件类?

[英]React propTypes component class?

How can I validate that the supplied prop is a component class (not instance)?如何验证提供的 prop 是组件类(不是实例)?

eg例如

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

For anyone using PropTypes >= 15.7.0 a new PropTypes.elementType was added in this pull request and was released on february 10, 2019 .对于使用PropTypes >= 15.7.0的任何人,此拉取请求中添加了新的PropTypes.elementType并于20192 月 10 日发布。

This prop type supports all components (native components, stateless components, stateful components, forward refs React.forwardRef , context providers/consumers).这个 prop 类型支持所有组件(原生组件、无状态组件、有状态组件、前向引用React.forwardRef 、上下文提供者/消费者)。

And it throws a warning when is not any of those elements, it also throws a warning when the prop passed is an element ( PropTypes.element ) and not a type.当不是这些元素中的任何一个时,它会发出警告,当传递的道具是元素( PropTypes.element )而不是类型时,它也会发出警告。

Finally you can use it like any other prop type:最后,您可以像使用任何其他道具类型一样使用它:

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

EDITED: Added React's FancyButton example to codesandbox as well as a custom prop checking function that works with the new React.forwardRef api in React 16.3.编辑:向代码和添加了 React 的FancyButton示例,以及与 React 16.3 中的新React.forwardRef api 一起使用的自定义道具检查功能。 The React.forwardRef api returns an object with a render function. React.forwardRef api 返回一个带有render函数的对象。 I'm using the following custom prop checker to verify this prop type.我正在使用以下自定义道具检查器来验证此道具类型。 - Thanks for Ivan Samovar for noticing this need. - 感谢 Ivan Samovar 注意到这一需求。

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

You'll want to use你会想要使用PropTypes.element . . Actually... PropType.func works for both stateless functional components and class components.实际上... PropType.func适用于无状态功能组件和类组件。

I've made a sandbox to prove that this works... Figured this was needed considering I gave you erroneous information at first.我做了一个沙箱来证明这是有效的......考虑到我一开始给你错误的信息,我认为这是必要的。 Very sorry about that!对此非常抱歉!

Working sandbox example !工作沙箱示例

Here is the code for the test in case link goes dead:这是测试链接失效时的代码:

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'));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM