React - как определить, является ли компонент апатридом/функциональным?

У меня есть функциональный/нестационарный компонент и компонент, унаследованный от React.Component:

const Component1 = () => (<span>Hello</span>)

class Component2 extends React.Component {
  render() {
    return (<span>Hello</span>)
  }
}

Как определить, является ли компонент апатридом или нет? Есть ли официальный способ?

isStateless(Component1) // true
isStateless(Component2) // false

Ответ 1

вы можете проверить его прототип, например:

function isStateless(Component) {
    return !Component.prototype.render;
}

Ответ 2

Компоненты класса по своей сути являются состояниями, но с появлением хуков React функциональные компоненты больше не называются не имеющими состояния, потому что они также могут быть и состоящими.

Специальное свойство isReactComponent существует в React.Component начиная с React.Component 0.14. Это позволяет определить, является ли компонент компонентом класса.

function isFunctionalComponent(Component) {
  return (
    typeof Component === 'function' // can be various things
    && !(
      Component.prototype // native arrows don't have prototypes
      && Component.prototype.isReactComponent // special property
    )
  );
}

function isClassComponent(Component) {
  return !!(
    typeof Component === 'function'
    && Component.prototype
    && Component.prototype.isReactComponent
  );
}

Подобные проверки выполняются в базе кода React.

Поскольку компоненты могут быть различными вещами, такими как Provider контекста или Consumer, isFunctionalComponent(Component) может быть не равен !isClassComponent(Component).

Ответ 3

Зависит от того, что называют "лицами без гражданства". Если под лицом без состояния подразумевается "не может быть ref ", то это:

function isStateless(Component) {
  return typeof Component !== 'string' && !Component.prototype.render
}

Обновление: появился также новый тип PropTypes.elementType для компонентов React (не "элементов").