React 可以渲染什么类型的东西?

What type to use for things React can render?

我有一个组件使用道具作为渲染组件。既然 React 提供了这么多方法来创建组件 类,那么这个 prop 的类型注解应该是什么?

在下面的示例中,Wrap 的正确类型注释是什么?

import React from 'react'

function Wrap ({ component: Component }) {
  return <Component foo />
}

class ClassComponent extends React.Component {
  render () {
    return <div>foo: {this.props.foo}</div>
  }
}
class ClassPureComponent extends React.PureComponent {
  render () {
    return <div>foo: {this.props.foo}</div>
  }
}

const CreateClassComponent = ReactClass.createClass({
  render () {
    return <div>foo: {this.props.foo}</div>
  }
})

function PureFunctionComponent ({ foo }) {
  return <div>foo: {foo}</div>
}

// These should all be valid
<Wrap component={ClassComponent} />
<Wrap component={ClassPureComponent} />
<Wrap component={CreateClassComponent} />
<Wrap component={PureFunctionComponent} />

我认为 ReactClass<any> 是您要找的类型。

// @flow
import React from 'react'

function Wrap ({ component: Component }: {component: ReactClass<any>}) {
  return <Component foo />
}

class ClassComponent extends React.Component {
  render () {
    return <div>foo: {this.props.foo}</div>
  }
}

class ClassPureComponent extends React.PureComponent {
  render () {
    return <div>foo: {this.props.foo}</div>
  }
}

const CreateClassComponent = React.createClass({
  render () {
    return <div>foo: {this.props.foo}</div>
  }
});

function PureFunctionComponent ({ foo }) {
  return <div>foo: {foo}</div>
}

// These should all be valid

<Wrap component={ClassComponent} />;
<Wrap component={ClassPureComponent} />;
<Wrap component={CreateClassComponent} />;
<Wrap component={PureFunctionComponent} />;

Example on flowtype.org/try

有一个反应高阶组件的例子here in the docs

使用 ReactClass<any> 是不安全的,因为它允许

<Wrap component={(props: {bar: string}) => <div>{props.bar}</div>} />;

类型安全替代

type FunctionComponent<P> = (props: P) => ?React$Element<any>;
type ClassComponentT<D, P, S> = Class<React$Component<D, P, S>>;
type Component<D, P, S> = ClassComponentT<D, P, S> | FunctionComponent<P>;

function Wrap ({ component: Component }: {component: Component<void, { foo: any }, void>}) {
  return <Component foo />
}