Reputation: 1971
I want to pass a React component as input prop to another React component. I tried to reference it as React.Component<*, *, *> but when I use the passed component in the render method I get an error. This is how I wrote out my flow code.
/* @flow */
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
const Input = props => <div>Yo</div>
type DefaultProps = {
InputComponent: Input
};
type Props = {
InputComponent: React.Component<*, *, *>
};
class App extends Component<DefaultProps, Props, void> {
static defaultProps = {
InputComponent: Input
};
props: Props;
render() {
const { InputComponent } = this.props
return (
<div>
<InputComponent />
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
However in the App render method I get the error
React element `InputComponent` (Expected React component instead of React$Component)
How should I properly type input components?
Upvotes: 16
Views: 3107
Reputation: 1
On version Flow 0.93.0, you can do the following.
import type { Element as ReactElement } from 'react'; type Props = { component: ReactElement }
Upvotes: 0
Reputation: 1255
Since v0.59.0, you should use React.Component. For example:
/* @flow */
import React from 'react';
const Input = props => <div>Yo</div>
type Props = {
InputComponent: React.Component<*, *>
};
class App extends React.Component<Props, void> {
static defaultProps = {
InputComponent: Input
};
render() {
const { InputComponent } = this.props
return (
<div>
<InputComponent />
</div>
)
}
}
Here is a working example for 0.59.0. As mentioned in the comments, there is a description of the changes here.
:: Before v0.59.0 ::
You should use ReactClass<*>
instead of React.Component
.
Here is a working example, and the documentation is here!
/**
* Type of a React class (not to be confused with the type of instances of a
* React class, which is the React class itself). A React class is any subclass
* of React$Component. We make the type of a React class parametric over Config,
* which is derived from some of the type parameters (DefaultProps, Props) of
* React$Component, abstracting away others (State); whereas a React$Component
* type is useful for checking the definition of a React class, a ReactClass
* type (and the corresponding React$Element type, see below) is useful for
* checking the uses of a React class. The required constraints are set up using
* a "helper" type alias, that takes an additional type parameter C representing
* the React class, which is then abstracted with an existential type (*). The *
* can be thought of as an "auto" instruction to the typechecker, telling it to
* fill in the type from context.
*/
type ReactClass<Config> = _ReactClass<*, *, Config, *>;
type _ReactClass<DefaultProps, Props, Config: $Diff<Props, DefaultProps>, C: React$Component<DefaultProps, Props, any>> = Class<C>;
Upvotes: 12