在我的React项目中获得“无法将类作为函数调用”


129

我正在尝试将React map组件添加到我的项目中,但是遇到错误。我使用Fullstack React的博客文章作为参考。我在google_map.js第83行中查找了引发错误的位置:

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

到目前为止,这是我的地图组件。当我注释掉第58-60行(最后三行)时,页面加载正常(没有地图)。编辑:我做了@Dmitriy Nevzorov建议的更改,它仍然给我相同的错误。

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)

这是在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'))

2
您有两个export defaultS,new GoogleAPIComponent()不是GoogleAPIComponent()吗?
gcampbell '16

我删除了默认设置之一,并尝试了您的建议。看起来它现在实际上正在与Google Maps通信,这很好,但是在页面加载之前,它引发了另一个神秘的错误:Locations.js:58 Uncaught TypeError :(中间值)不是一个函数。”有什么想法吗?
Mike Fleming

1
如果您删除了该(LocationContainer)怎么办?
gcampbell '16

谢谢,我想知道了!很奇怪,这就是他们将其写在博客文章中的方式。仍然会从Google Maps中收到其他一些错误,我将其放在此处:'GoogleMap:已弃用apiKey,请改用bootstrapURLKeys = {{key:YOUR_API_KEY}}。google_map.js:689的GoogleMap:中心或defaultCenterproperty必须定义google_map.js:699的GoogleMap:放大或defaultZoomproperty必须定义google_map.js:704'
麦克弗莱明

1
我不确定其他错误,但是您可以尝试解决第一个错误:export default new GoogleApiComponent({ bootstrapURLKeys: MY_API_KEY })
gcampbell '16

Answers:


206

对我来说,发生在我忘了写extends React.Component最后的时候。我知道这并不是您所拥有的,但是希望阅读此答案的其他人可以从中受益。


19
有这可以解释为什么这个伟大的工程后,在反应过度overreacted.io/how-does-react-tell-a-class-from-a-function
埃里克Kigathi

1
文章摘要:在浏览器中区分类和函数实际上并不完全是琐碎的……“实际的解决方案确实很简单,但是[我要继续]大量的切线解释了为什么React最终使用此解决方案。 “。”等等,等等,等等->“如果不扩展React.Component,React将不会在原型上找到isReactComponent,也不会将组件视为类。”
spinkus

70

对我来说是因为我忘了使用 new在设置Animated状态时关键字。

例如:

fadeAnim: Animated.Value(0),

fadeAnim: new Animated.Value(0),

会解决它。


1
这解决了我的问题,我使用了一个不是动画的用例,而是使用了new关键字解决了它。谢谢
Olivier JM

3
花了4个小时44分4秒试图知道发生了什么。你是上帝
Satheeshwaran

是的,那也是我。谢谢!
James Cushing

64

tl; dr

如果您使用React Router v4,请检查您的<Route/>组件是否确实使用了component prop来传递基于类的React组件!

更一般而言:如果您的类看起来不错,请检查调用该类的代码是否不尝试将其用作函数。

说明

我得到这个错误,因为我是用路由器做出反应v4和我无意中使用的render道具,而不是component一个在<Route/>分量通过我的组件,这是一类。这是一个问题,因为render期望(调用)一个函数,而component可以在React组件上运行。

所以在这段代码中:

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

包含<Route/>组件的行应这样编写:

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

令人遗憾的是,他们不检查它并给出了这样的错误并易于发现错误。


47

发生在我身上,因为我曾经

PropTypes.arrayOf(SomeClass)

代替

PropTypes.arrayOf(PropTypes.instanceOf(SomeClass))


谢谢,错误的PropTypes定义是我的问题。
Vasiliy

这解决了我的问题!是PropTypes.oneOfType([SomeClass, SomeOtherClass]).isRequired,代替 PropTypes.oneOfType([PropTypes.instanceOf(SomeClass), PropTypes.instanceOf(SomeOtherClass)]).isRequired,
道格

谢谢,真的很久以来一直在想那里出了什么问题!
得到了发烧媒体

14

您有重复的export default声明。第一个被第二个覆盖,第二个实际上是一个函数。


接得好!我将默认值保留在GoogleApiComponent的前面,但仍然出现相同的错误。另外,删除所有默认设置会在我的GoogleApiComponent终端上给我一个“意外令牌”错误。
Mike Fleming

14

对我而言,它ComponentName.prototype不是ComponentName.propTypesPhpstormIDE 自动建议。希望它会帮助某人。


14

我遇到了同样的问题,因为我的ES6组件类没有扩展React.Component


8

通常,当您错过扩展React 组件时,会发生以下问题:

import React, {Component} from 'react'

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

7

对我来说是因为我使用原型而不是propTypes

class MyComponent extends Component {

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

MyComponent.prototype = {

};

应该是

MyComponent.propTypes = {

};

对我来说完全一样。谢谢!
泰克森

6
Post.proptypes = {

}

Post.propTypes = {

}

有人应该评论如何以非常精确的方式监视此类错误。


1
最好用一些详细信息来解释您的解决方案/答案。
Dharmang '18年

没错,好极了!
姆班达

3

似乎没有单个情况出现此错误。

当我没有在statefull组件中声明构造函数时,发生在我身上。

class MyComponent extends Component {

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

代替

class MyComponent extends Component {

    constructor(props) {
        super(props);
    }

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

3

您可以检查的两件事是,

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

Slider.propTypes = {
    // accessibility: PropTypes.bool,
}
  • 确保您扩展了React.Component
  • 使用propTypes代替原型(根据IDE intellisense)

应该是Slider.propTypes:{}
David Casanellas

2

这是一个普遍的问题,不会一次出现。但是,在所有情况下,常见的问题是您忘记import了特定的组件(无论是来自安装的库还是来自创建的定制组件,这都无关紧要):

import {SomeClass} from 'some-library'

以后使用它时,如果不导入它,则编译器会认为它是一个函数。因此,它打破了。这是一个常见的示例:

imports

...code...

然后在代码中的某个地方

<Image {..some props} />

如果您忘记导入组件,<Image />则编译器将不会像其他导入那样抱怨,但是在到达代码时会中断。


1

对我来说,这是因为我不小心删除了我的render方法!

componentWillReceiveProps在短render方法之前,我有一个不再需要的方法的类。匆忙删除它时,我也意外删除了整个render方法。

这是一个PAIN追查,因为我得到在完全不相干的文件作为该问题的“根源”意见指向控制台的错误。




1

对我来说,发生这种情况是因为我没有正确包装连接函数,并试图导出默认的两个组件


1

导入错误的并指向错误的存储区时遇到了此错误在react-native中使用mobx时,。

我在此代码段中遇到错误:

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

@inject ("counter")
@Observer

经过如下几段修正后。我这样解决了我的问题。

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

@inject("counterStore")
@observer

实际出了什么问题,我使用的是错误的类,而不是observer使用的是Observer,而不是counterStore使用的counter。我这样解决了我的问题。


1

在文件中 MyComponent.js

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

我放置了一些与该组件相关的功能:

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

export myFunction() {
...
}

然后在导入该功能的另一个文件中:

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

你能发现问题吗?

我忘了花括号,并MyComponent以名字输入myFunction

因此,解决方法是:

import {myFunction} from './MyComponent'

1

在导入函数而不是类时,错误地编写了import语句时,我遇到了这种情况。如果removeMaterial是另一个模块中的函数:

对:

import { removeMaterial } from './ClaimForm';

错误:

import removeMaterial from './ClaimForm';

1

我因犯小错误而收到此错误。我的错误是将类导出为函数而不是类。在班级文件的底部,我有:

export default InputField();

应该是什么时候:

export default InputField;

0

我也遇到了这个问题,您的react组件内部可能有一个javascript错误。确保如果您使用的是依赖项,则new在类上使用运算符实例化新实例。错误将抛出

this.classInstance = Class({})

代替使用

this.classInstance = new Class({})

您将在浏览器的错误链中看到

at ReactCompositeComponentWrapper._constructComponentWithoutOwner

我相信这就是赠品。



0

就我而言,我写错comment了地方Component

我只是写了这个。

import React, { Component } from 'react';

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

代替这个。

import React, { Component } from 'react';

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

这没什么大不了的,但是对于像我这样的初学者来说,这确实令人困惑。我希望这会有所帮助。


0

就我而言,使用JSX时,父组件正在调用其他没有“ <>”的组件

 <ComponentA someProp={someCheck ? ComponentX : ComponentY} />

固定

<ComponentA someProp={someCheck ? <ComponentX /> : <ComponentY />} />

0

另一个报告在这里:我导出时不起作用:

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

代替

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

注意括号的位置。两者都是正确的,不会被棉短绒,漂亮的东西或类似的东西所抓住。花了我一段时间来追踪它。


0

就我而言,我不小心将组件名称(Home)作为connect函数的第一个参数,而应该将其放在末尾。h

这个-当然-给我错误:

export default connect(Home)(mapStateToProps, mapDispatchToProps)

但这确实奏效了:

export default connect(mapStateToProps, mapDispatchToProps)(Home)

0

这是由于我render不正确地命名函数而引起的:

import React from 'react';

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

我出现此错误的原因仅是因为我的类没有适当的render方法。


0

实际上,所有问题都与redux连接。解决方案:

正确的

export default connect(mapStateToProps, mapDispatchToProps)(PageName)

错误与错误

export default connect(PageName)(mapStateToProps, mapDispatchToProps)

-1

对我而言,在rootReducer.js中错误导入了一个reducer。我导入了容器而不是reducer文件。

import settings from './pages/Settings';

但可以肯定的是

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

其中settings目录包含以下文件action.js,index.js,reducer.js。

要检查它,您可以从redux / es / redux.js中记录assertReducerShape()函数的reducers arg。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.