Reputation: 14086
I'm writing a React component that takes a renderer
property. In general, this is a function that takes in an object of arguments and returns another React component. However, I would like for users of my component to be able to pass in a React component class instead. I would then internally wrap that class in a function:
class MyComponent extends React.Component {
render() {
const { renderer } = this.props;
const renderFn = (renderer.isAComponentClass())
? (props => <renderer {...props} />)
: renderer;
return <div>{ renderFn(someArgs) }</div>;
}
}
Of course, in JavaScript, a class is also a function. How can I check whether renderer
is a class? I am using Babel 6.
I am aware that I could simple return <renderer {...someArgs} />
. I would rather not do this if I can avoid it, because this unnecessarily bloats the component tree.
Upvotes: 2
Views: 73
Reputation: 222498
It is possible to detect native classes with regular expression - as long as they don't implement toString
method that will change their representation as a string.
It is not possible to detect if a function is a class due to the fact that classes don't differ from functions in transpiled code. This is a good reason to not even try to distinguish them programmatically.
It is possible to check if React.Component
is the ancestor of a function/class with
renderer.prototype instanceof React.Component
Since this puts unnecessary restriction, a better option is to duck test it, like
renderer.prototype && ['render', 'setState', ...]
.map(methodName => typeof renderer.prototype[methodName])
.every(methodType => methodType === 'function')
However, none of these checks are accurate. prototype
property can be messed up in some cases, e.g. when a class is decorated. The only way to certainly know that a class is a component is to instantiate it first.
And API would be cleaner if renderer function and component could never be confused, for instance separate renderer
and rendererComponent
properties.
Upvotes: 1