react: Warn If a Component Doesn't Extend React.Component

To support arrow functions and plain functions as “components” we need to know if we can call new on them. Examples that won’t work:

function PlainFunctionComponent(props) {
  return null;
}

var ArrowFunctionComponent = (props) => <div />;

class ClassComponent {
  render() {
    return <div><PlainFunctionComponent /><ArrowFunctionComponent /></div>;
  }
}

We need to detect if a component is a “function” or a “class” before calling new on it.

We can call new on everything if they’re plain functions as long as they return a ReactElement. However, that won’t work for null/false/string return values and we want to support those too. We also can’t call new on arrow functions. Likewise, we can’t NOT call new on classes.

Unfortunately ECMAScript doesn’t have a way to detect if something is newable or not.

The current plan is to add our own static flag to React.Component so that we can detect if something is a class.

Any class pattern that doesn’t require new should still be possible:

function ModuleComponent(props) {
  return {
    render() {
      return <div />;
    }
  };
}

I’m not sure how we can distinguish this pattern from one that requires new for warnings though. 😦

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 16 (3 by maintainers)

Most upvoted comments

@rads That might be enough. A bit fragile. It also means that classes in ECMAScript can never have a default render function. 😃

We might have more than one way of rendering in the future. E.g. prerender / postrender / renderAtIndex. That might still work though.

Will need to check if there’s any difference in terms of engine optimizations between these options.

having to extend ReactComponent is a bit more annoying for stateless components

But if component is stateless you can just turn it into a function?

What about checking if ClassComponent.prototype.render is a function?