Изменить класс компонентов propTypes?

Как я могу проверить, что поставляемая поддержка является классом компонента (а не экземпляром)?

например.

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

Ответ 1

РЕДАКТИРОВАНИЕ: Добавлен пример React FancyButton для codesandbox, а также пользовательская функция проверки проп, которая работает с новым API React.forwardRef в React 16.3. API React.forwardRef возвращает объект с функцией render. Я использую следующую специальную проверку для подтверждения этого типа. - Спасибо за Ивана Самовара за то, что он заметил эту необходимость.

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 работает как для функциональных компонентов без сохранения состояния, так и для компонентов класса.

Я сделал песочницу, чтобы доказать, что это работает... Я подумал, что это нужно, учитывая, что сначала я дал вам ошибочную информацию. Очень сожалею об этом!

Пример рабочей песочницы !

Вот код для теста на случай, если ссылка не работает:

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

Ответ 2

Для тех, кто использует PropTypes >= 15.7.0 в этот запрос на добавление был добавлен новый PropTypes.elementType выпущенный 10 февраля 2019 года.

Этот тип поддержки поддерживает все компоненты (нативные компоненты, компоненты без состояния, компоненты с состоянием, прямые ссылки React.forwardRef, провайдеры/потребители контекста).

И он выдает предупреждение, когда нет ни одного из этих элементов, он также выдает предупреждение, когда пропущенный пропеллер является элементом (PropTypes.element), а не типом.

Наконец, вы можете использовать его как любой другой тип проп:

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