Getting "Cannot call a class as a function" in my React Project

JavascriptGoogle MapsReactjsEcmascript 6React Router

Javascript Problem Overview


I'm trying to add a React map component to my project but run into an error. I'm using Fullstack React's blog post as a reference. I tracked down where the error gets thrown in google_map.js line 83:

function _classCallCheck(instance, Constructor) { 
  if (!(instance instanceof Constructor)) { 
    throw new TypeError("Cannot call a class as a function"); 
    } 
  }

Here is my map component so far. The page loads just fine (without a map) when I comment out lines 58-60, the last three lines. edit: I made the changes that @Dmitriy Nevzorov suggested and it still gives me the same error.

import React from 'react'
import GoogleApiComponent from 'google-map-react'

export class LocationsContainer extends React.Component {
	constructor() {
		super()
	}
  render() {
  	const style = {
  		width: '100vw',
  		height: '100vh'
  	}
    return (
      <div style={style}>
      	<Map google={this.props.google} />
      </div>
    )
  }
}

export class Map extends React.Component {
	componentDidUpdate(prevProps, prevState){
		if (prevProps.google !== this.props.google){
			this.loadMap();
		}
	}
	componentDidMount(){
		this.loadMap();
	}
	loadMap(){
		if (this.props && this.props.google){
			const {google} = this.props;
			const maps = google.maps;

			const mapRef = this.refs.map;
			const node = ReactDOM.findDOMNode(mapRef);

			let zoom = 14;
			let lat = 37.774929
			let lng = 122.419416
			const center = new maps.LatLng(lat, lng);
			const mapConfig = Object.assign({}, {
				center: center,
				zoom: zoom
			})
			this.map = new maps.Map(node, mapConfig)
		}
	}
	render() {
		return (
			<div ref='map'>
				Loading map...
			</div>
		)
	}
}

export default GoogleApiComponent({
  apiKey: MY_API_KEY
})(LocationsContainer)

And here is where this map component gets routed in main.js:

import {render} from 'react-dom';
import React from 'react';
import Artists from './components/Artists'
import { Router, Route, Link, browserHistory } from 'react-router'
import Home from './components/HomePage'
import Gallery from './components/ArtGallery'
import ArtistPage from './components/ArtistPage'
import FavsPage from './components/FavsPage'
import LocationsContainer from './components/Locations'

//Create the route configuration
render((
  <Router history={browserHistory}>
    <Route path="/" component={Home} />
    	<Route path="locations" component={LocationsContainer} />
    	<Route path="artists" component={Artists} /> 
	    <Route path="gallery" component={Gallery} />     
      <Route path="favorites" component={FavsPage} />
      <Route path=":artistName" component={ArtistPage} />
  </Router>
), document.getElementById('app'))

Javascript Solutions


Solution 1 - Javascript

For me it happened when I forgot to write extends React.Component at the end. I know it's not exactly what YOU had, but others reading this answer can benefit from this, hopefully.

Solution 2 - Javascript

For me it was because I forgot to use the new keyword when setting up Animated state.

eg:

fadeAnim: Animated.Value(0),

to

fadeAnim: new Animated.Value(0),

would fix it.

Solution 3 - Javascript

tl;dr

If you use React Router v4 check your <Route/> component if you indeed use the component prop to pass your class based React component!

More generally: If your class seems ok, check if the code that calls it doesn't try to use it as a function.

Explanation

I got this error because I was using React Router v4 and I accidentally used the render prop instead of the component one in the <Route/> component to pass my component that was a class. This was a problem, because render expects (calls) a function, while component is the one that will work on React components.

So in this code:

<HashRouter>
    <Switch>
        <Route path="/" render={MyComponent} />
    </Switch>
</HashRouter>

The line containing the <Route/> component, should have been written like this:

<Route path="/" component={MyComponent} />

It is a shame, that they don't check it and give a usable error for such and easy to catch mistake.

Solution 4 - Javascript

Happened to me because I used

PropTypes.arrayOf(SomeClass)

instead of

PropTypes.arrayOf(PropTypes.instanceOf(SomeClass))

Solution 5 - Javascript

For me, it was ComponentName.prototype instead of ComponentName.propTypes. auto suggested by Phpstorm IDE. Hope it will help someone.

Solution 6 - Javascript

You have duplicated export default declaration. The first one get overridden by second one which is actually a function.

Solution 7 - Javascript

I experienced the same issue, it occurred because my ES6 component class was not extending React.Component.

Solution 8 - Javascript

Mostly these issues occur when you miss extending Component from react:

import React, {Component} from 'react'

export default class TimePicker extends Component {
    render() {
        return();     
    }
}

Solution 9 - Javascript

For me it was because i used prototype instead of propTypes

class MyComponent extends Component {

 render() {
    return <div>Test</div>;
  }
}

MyComponent.prototype = {

};

it ought to be

MyComponent.propTypes = {

};

Solution 10 - Javascript

Post.proptypes = {

}

to

Post.propTypes = {

}

someone should comment on how to monitor such error in a very precise way.

Solution 11 - Javascript

Two things you can check is,

class Slider extends React.Component {
    // Your React Code
}

Slider.propTypes = {
    // accessibility: PropTypes.bool,
}
  • Make sure that you extends React.Component
  • Use propTypes instead of prototype (as per IDE intellisense)

Solution 12 - Javascript

Looks like there're no single case when this error appears.

Happened to me when I didn't declare constructor in statefull component.

class MyComponent extends Component {

	render() {
	    return <div>Test</div>;
    }
}

instead of

class MyComponent extends Component {

    constructor(props) {
	    super(props);
    }

	render() {
	    return <div>Test</div>;
    }
}

Solution 13 - Javascript

This is a general issue, and doesn't appear in a single case. But, the common problem in all the cases is that you forget to import a specific component (doesn't matter if it's either from a library that you installed or a custom made component that you created):

import {SomeClass} from 'some-library'

When you use it later, without importing it, the compiler thinks it's a function. Therefore, it breaks. This is a common example:

imports

...code...

and then somewhere inside your code

<Image {..some props} />

If you forgot to import the component <Image /> then the compiler will not complain like it does for other imports, but will break when it reaches your code.

Solution 14 - Javascript

In file MyComponent.js

export default class MyComponent extends React.Component {
...
}

I put some function related to that component:

export default class MyComponent extends React.Component {
...
}

export myFunction() {
...
}

and then in another file imported that function:

import myFunction from './MyComponent'
...
myFunction() // => bang! "Cannot call a class as a function"
...

Can you spot the problem?

I forgot the curly braces, and imported MyComponent under name myFunction!

So, the fix was:

import {myFunction} from './MyComponent'

Solution 15 - Javascript

I received this error by making small mistake. My error was exporting the class as a function instead of as a class. At the bottom of my class file I had:

export default InputField();

when it should have been:

export default InputField;

Solution 16 - Javascript

For me, it was because I'd accidentally deleted my render method !

I had a class with a componentWillReceiveProps method I didn't need anymore, immediately preceding a short render method. In my haste removing it, I accidentally removed the entire render method as well.

This was a PAIN to track down, as I was getting console errors pointing at comments in completely irrelevant files as being the "source" of the problem.

Solution 17 - Javascript

I had a similar problem I was calling the render method incorrectly

Gave an error:

render = () => {
    ...
}

instead of

correct:

render(){
    ...
}

Solution 18 - Javascript

I had it when I did so :

function foo() (...) export default foo

correctly:

export default  () =>(...);

or

const foo = ...
export default foo

Solution 19 - Javascript

For me it happened because I didn't wrap my connect function properly, and tried to export default two components

Solution 20 - Javascript

I faced this error when I imported the wrong class and referred to wrong store while using mobx in react-native.

I faced error in this snippet :

import { inject, Observer } from "mobx-react";

@inject ("counter")
@Observer

After few corrections like as below snippet. I resolved my issue like this way.

import { inject, observer } from "mobx-react";

@inject("counterStore")
@observer

What was actually wrong,I was using the wrong class instead of observer I used Observer and instead of counterStore I used counter. I solved my issue like this way.

Solution 21 - Javascript

I experienced this when writing an import statement wrong while importing a function, rather than a class. If removeMaterial is a function in another module:

Right:

import { removeMaterial } from './ClaimForm';

Wrong:

import removeMaterial from './ClaimForm';

Solution 22 - Javascript

I have also run into this, it is possible you have a javascript error inside of your react component. Make sure if you are using a dependency you are using the new operator on the class to instantiate the new instance. Error will throw if

this.classInstance = Class({})

instead use

this.classInstance = new Class({})

you will see in the error chain in the browser

at ReactCompositeComponentWrapper._constructComponentWithoutOwner

that is the giveaway I believe.

Solution 23 - Javascript

In my case i wrote comment in place of Component by mistake

I just wrote this.

import React, { Component } from 'react';

  class Something extends Component{
      render() {
          return();
     }
  }

Instead of this.

import React, { Component } from 'react';

  class Something extends comment{
      render() {
          return();
     }
  }

it's not a big deal but for a beginner like me it's really confusing. I hope this will be helpfull.

Solution 24 - Javascript

Solution 25 - Javascript

Another report here: It didn't work as I exported:

export default compose(
  injectIntl,
  connect(mapStateToProps)(Onboarding)
);

instead of

export default compose(
  injectIntl,
  connect(mapStateToProps)
)(Onboarding);

Note the position of the brackets. Both are correct and won't get caught by either a linter or prettier or something similar. Took me a while to track it down.

Solution 26 - Javascript

In my case, I accidentally put component name (Home) as the first argument to connect function while it was supposed to be at the end. duh.

This one -surely- gave me the error:

export default connect(Home)(mapStateToProps, mapDispatchToProps)

But this one worked -surely- fine:

export default connect(mapStateToProps, mapDispatchToProps)(Home)

Solution 27 - Javascript

This occured when I accidentally named my render function incorrectly:

import React from 'react';

export class MyComponent extends React.Component {
  noCalledRender() {
    return (
      <div>
        Hello, world!
      </div>
    );
  }
}

My instance of this error was simply caused because my class did not have a proper render method.

Solution 28 - Javascript

Actually all the problem redux connect. solutions:

Correct:

export default connect(mapStateToProps, mapDispatchToProps)(PageName)

Wrong & Bug:

export default connect(PageName)(mapStateToProps, mapDispatchToProps)

Solution 29 - Javascript

In my scenario I was attempting to use hot reloading on a custom hook (not sure why, probably just muscle memory when creating components).

const useCustomHook = () => {
    const params = useParams();
    return useSelector(
        // Do things
    );
};

// The next line is what breaks it
export default hot(module)(useCustomHook);

The correct way

const useCustomHook = () => {
    const params = useParams();
    return useSelector(
        // Do things
    );
};

export default useCustomHook;

Apparently you can't hot reload hook  

Solution 30 - Javascript

For me it was a wrong import of a reducer in the rootReducer.js. I imported container instead of reducer file.

Example

import settings from './pages/Settings';

But sure it should be

import settings from './pages/Settings/reducer';

Where settings directory contains following files actions.js, index.js, reducer.js.

To check it you can log reducers arg of the assertReducerShape() function from the redux/es/redux.js.

Solution 31 - Javascript

If you're on Node JS and you're seeing this error in a Class you've added to support a Cucumber test, it's because Cucumber will automatically try to run anything that exports a function, and NodeJS internally converts a Class to a function.

So instead of this:

module.exports = MyClass;

do this:

module.exports.MyClass = MyClass;

Then, when you import it into your steps file, do it like this:

let MyClass = require("myclass.js").MyClass;

This way you're not exporting a function. Read more here.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMike FlemingView Question on Stackoverflow
Solution 1 - JavascriptprogrammerView Answer on Stackoverflow
Solution 2 - JavascriptWilliam ParkView Answer on Stackoverflow
Solution 3 - JavascripttotymedliView Answer on Stackoverflow
Solution 4 - JavascriptDan BalabanView Answer on Stackoverflow
Solution 5 - JavascriptcodersaifView Answer on Stackoverflow
Solution 6 - JavascriptDmitriy NevzorovView Answer on Stackoverflow
Solution 7 - JavascriptJamView Answer on Stackoverflow
Solution 8 - Javascriptjeff ayanView Answer on Stackoverflow
Solution 9 - JavascriptOnengiye RichardView Answer on Stackoverflow
Solution 10 - JavascriptMbandaView Answer on Stackoverflow
Solution 11 - JavascriptDipen DedaniaView Answer on Stackoverflow
Solution 12 - JavascriptPavlo KozlovView Answer on Stackoverflow
Solution 13 - JavascriptTim PegasView Answer on Stackoverflow
Solution 14 - JavascriptMikhail VasinView Answer on Stackoverflow
Solution 15 - JavascriptairvineView Answer on Stackoverflow
Solution 16 - JavascriptAlex McMillanView Answer on Stackoverflow
Solution 17 - JavascriptEmile EsterhuizenView Answer on Stackoverflow
Solution 18 - JavascriptJe kaView Answer on Stackoverflow
Solution 19 - JavascriptDmitriyView Answer on Stackoverflow
Solution 20 - JavascriptbadarshahzadView Answer on Stackoverflow
Solution 21 - JavascriptshackerView Answer on Stackoverflow
Solution 22 - JavascriptmibbitView Answer on Stackoverflow
Solution 23 - JavascriptUddesh JainView Answer on Stackoverflow
Solution 24 - JavascriptAlanView Answer on Stackoverflow
Solution 25 - JavascriptSebastijan DumančićView Answer on Stackoverflow
Solution 26 - JavascriptscaryguyView Answer on Stackoverflow
Solution 27 - JavascriptBryan BorView Answer on Stackoverflow
Solution 28 - JavascriptBatuhan OrhanView Answer on Stackoverflow
Solution 29 - JavascriptBryantView Answer on Stackoverflow
Solution 30 - JavascriptOleg ShishkovView Answer on Stackoverflow
Solution 31 - JavascriptRyan ShillingtonView Answer on Stackoverflow