Over a million developers have joined DZone.

Livecoding: You Can’t Extend an Object

DZone's Guide to

Livecoding: You Can’t Extend an Object

A DZone MVB tries to tackle of extending an object using the JavaScript framework, React. Read and watch to see who he handles it!

· Web Dev Zone ·
Free Resource

Read this guide to learn everything you need to know about RPA, and how it can help you manage and automate your processes.

Today we battled with a fearsome error, an error of odd implications and no clear solutions. Uncaught TypeError: Super expression must either be null or function

What does that even mean!?

Well, it means that when you import TransitionableComponent from 'react-transitionable-component', you get an object instead of a function. We confirmed the problem with some console.log calls. After importing TransitionableComponent as an object.

It's an object!

It looks just like a React component is supposed to. There’s a constructor method, a bunch of default object methods, and – I assume – all the Component methods as well. That’s great when you want to use a component in your render() function. Not so great when you want to use it as a parent class.

When you do something like class Arc extends TransitionableComponent, it fails. You can extend a null or a function, but not an object.

You can inherit from a class, but not from an instance of a class. I’m sure it’s like that in every language, but the reason it’s like that in JavaScript is that class TransitionableComponent extends Component transpiles into:

var TransitionableComponent = function (_Component) {
        _inherits(TransitionableComponent, _Component);

        function TransitionableComponent(props) {
            _classCallCheck(this, TransitionableComponent);

                    // I think this is super(props)
            var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(TransitionableComponent).call(this, props));

            // this is where your constructor body goes
            return _this;

        _createClass(TransitionableComponent, [{
           // this is where your class body goes

        return TransitionableComponent;

That _inherits call is the crucial piece. It does a bunch of .prototype magic to extend the definition of a given class with the definition of a child class. Instances don’t have prototypes, functions do.

Functions have a prototype property because of legacy reasons, I’m sure. That’s how JavaScript has always understood the concept of classes – generator/constructor functions double as classes.

At this point, TransitionableComponent is a function – just like we’d expect. With some console.log-ing we confirmed that it remains a function right up until the point where we import it in our sample project.


I don’t know why it becomes an object. Our guessing and prodding didn’t reveal much. This is what importing transpiles to:

var _TransitionableComponent = __webpack_require__(16);

var _TransitionableComponent2 = _interopRequireDefault(_TransitionableComponent);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

This code might return an object if you’re importing something that isn’t an ES6 Module. But we know that’s not our problem because TransitionableComponent.default is undefined.

You’d think __webpack_require__ was instantiating our component and returning an object instead of a function, but it works correctly when you import React’s default Component. Curiously, React’s compiled code looks like normal ES5 without even a hint of Webpack or Babel.


I am at a loss. I have no idea what’s going on or why. But until we figure this out, react-transitionable-component will not be a usable library and my chance at open-source glory lays trampled in the wastelands of npmjs.com.

Get the senior executive’s handbook of important trends, tips, and strategies to compete and win in the digital economy.

web dev ,react ,javascript

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}