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

时间:2016-07-20 12:52:01

标签: javascript google-maps reactjs ecmascript-6 react-router

我正在尝试将React地图组件添加到我的项目中但遇到错误。我使用Fullstack React的blog post作为参考。我在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'))

33 个答案:

答案 0 :(得分:163)

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

答案 1 :(得分:58)

TL;博士

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

更一般地说:如果您的课程似乎没问题,请检查调用它的代码是否尝试将其用作函数。

说明

我收到此错误是因为我使用的是React Router v4而我偶然使用了render道具而不是component组件中的<Route/>道具传递了我的组件。这是一个问题,因为render期望(调用)一个函数,而component是一个可以在React组件上工作的函数。

所以在这段代码中:

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

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

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

遗憾的是,他们没有检查它并为这样容易发现错误提供了可用的错误。

答案 2 :(得分:46)

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

例如:

fadeAnim: Animated.Value(0),

fadeAnim: new Animated.Value(0),

会解决它。

答案 3 :(得分:42)

因为我使用了

而发生在我身上

PropTypes.arrayOf(SomeClass)

而不是

PropTypes.arrayOf(PropTypes.instanceOf(SomeClass))

答案 4 :(得分:11)

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

答案 5 :(得分:11)

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

答案 6 :(得分:9)

对我来说,它是ComponentName.prototype而不是ComponentName.propTypes。 由Phpstorm IDE建议的自动。希望它会帮助别人。

答案 7 :(得分:7)

当您错过从react:

扩展组件时,通常会出现这些问题
import React, {Component} from 'react'

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

答案 8 :(得分:6)

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

class MyComponent extends Component {

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

MyComponent.prototype = {

};

应该是

MyComponent.propTypes = {

};

答案 9 :(得分:3)

Post.proptypes = {

}

Post.propTypes = {

}

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

答案 10 :(得分:2)

当出现此错误时,看起来没有单一案例。

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

class MyComponent extends Component {

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

而不是

class MyComponent extends Component {

    constructor(props) {
        super(props);
    }

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

答案 11 :(得分:1)

我有一个类似的问题,我不正确地调用渲染方法

发生错误:

render(){
    ...
}

而不是

正确:

SSLSession

答案 12 :(得分:1)

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

export default InputField();

应该在什么时候出现:

export default InputField;

答案 13 :(得分:1)

当我这样做时,我已经拥有它了:

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

正确:

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

const foo = ...
export default foo

答案 14 :(得分:1)

对我来说,这是因为我没有正确包装我的连接功能,并试图导出默认的两个组件

答案 15 :(得分:1)

当我在react-native中使用mobx导入错误的 class 并引用错误的 store 时,我遇到了此错误。

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

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

@inject ("counter")
@Observer

进行了一些如下所示的更正后。我是这样解决问题的。

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

@inject("counterStore")
@observer

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

答案 16 :(得分: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'

答案 17 :(得分:1)

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

右:

import { removeMaterial } from './ClaimForm';

错误:

import removeMaterial from './ClaimForm';

答案 18 :(得分:0)

实际上所有问题都可以连接。解决方案:

正确

export default connect(mapStateToProps, mapDispatchToProps)(PageName)

错误和错误

export default connect(PageName)(mapStateToProps, mapDispatchToProps)

答案 19 :(得分:0)

您可以检查的两件事是

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

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

答案 20 :(得分:0)

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

import {SomeClass} from 'some-library'

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

imports

...code...

然后在代码中的某处

<Image {..some props} />

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

答案 21 :(得分:0)

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

import React from 'react';

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

此错误的实例仅是由于我的类没有适当的render方法引起的。

答案 22 :(得分:0)

在我的情况下,我不小心将组件名称(Home)作为connect函数的第一个参数,而应该将其结尾。嗯。

这个-肯定-给我错误:

export default connect(Home)(mapStateToProps, mapDispatchToProps)

但是这个很好-

export default connect(mapStateToProps, mapDispatchToProps)(Home)

答案 23 :(得分:0)

在我的场景中,我试图在自定义钩子上使用热重载(不知道为什么,可能只是创建组件时的肌肉记忆)。

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

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

正确的方法

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

export default useCustomHook;

显然你不能热重载钩子??

答案 24 :(得分:0)

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

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

代替

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

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

答案 25 :(得分:0)

在我的情况下,使用JSX,父组件正在调用其他没有“ <>”的组件

 Array
(
    [Sam] => Array
        (
            [0] => Clinical Code
            [1] => 0
            [2] => Clinical Tweak
            [3] => 0
            [4] => Collector Code
            [5] => 0
            [6] => Collector Tweak
            [7] => 5
        )
    [John] => Array
        (
            [0] => Clinical Code
            [1] => 0
            [2] => Clinical Tweak
            [3] => 0
            [4] => Collector Code
            [5] => 5
            [6] => Collector Tweak
            [7] => 42
        )
    [Dona] => Array
        (
            [0] => Clinical Code
            [1] => 0
            [2] => Clinical Tweak
            [3] => 37
            [4] => Collector Code
            [5] => 0
            [6] => Collector Tweak
            [7] => 35
        )
   [Ricky] => Array
        (
            [0] => Clinical Code
            [1] => 7
            [2] => Clinical Tweak
            [3] => 50
            [4] => Collector Code
            [5] => 4
            [6] => Collector Tweak
            [7] => 17
        )
)

修复

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

答案 26 :(得分: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();
     }
  }

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

答案 27 :(得分:0)

尝试停止HMR并再次点击npm start以重建项目。
这,使错误消失,不知道为什么。

答案 28 :(得分:0)

对我来说,这是因为我不小心删除了我的select a.* from a except select b.* from b; 方法!

我有一个我不再需要render方法的课程,紧接在一个简短的componentWillReceiveProps方法之前。在我仓促删除它时,我不小心删除了整个render方法。

这是一个 PAIN 来跟踪,因为我收到控制台错误,指向完全不相关的文件中的评论作为问题的“来源”。

答案 29 :(得分:-1)

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

示例

import settings from './pages/Settings';

但是请确保它是

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

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

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

答案 30 :(得分:-1)

我也遇到过这种情况,你的反应组件内部可能存在javascript错误。确保您使用的依赖项是否正在使用类上的this.classInstance = Class({})运算符来实例化新实例。如果

,则会抛出错误

this.classInstance = new Class({})

改为使用

at ReactCompositeComponentWrapper._constructComponentWithoutOwner

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

{{1}}

这是我相信的赠品。

答案 31 :(得分:-2)

如果您使用的是Node JS,并且您在为支持黄瓜测试而添加的类中看到此错误,那是因为Cucumber会自动尝试运行任何导出一个函数,NodeJS在内部将一个Class转换为一个函数。

所以不要这样:

template<typename Func, typename ...Args>
auto inject_unique(Func f, Args &&...args)
{
  using out_type = decltype(f(std::forward<Args>(args)...));
  return std::unique_ptr<out_type>(new auto(f(std::forward<Args>(args)...)));
}

auto ptr = inject_unique([]() {return positioned({1, 2});});

这样做:

module.exports = MyClass;

然后,当您将其导入步骤文件时,请执行以下操作:

module.exports.MyClass = MyClass;

这样您就不会导出功能了。阅读更多here

答案 32 :(得分:-3)

嗨,在我的情况下,这里的解决方案不起作用 我的代码:

<强> index.js

import App from './App';

let store = createStore(App);

render(
    <Provider store={store}>
        <Router history={browserHistory}>
            <Route path="/" name='Strona główna' component={App}>
                <IndexRoute name='' component={Welcome}/>
                <Route name='Dashboard' path="dashboard" component={ReatEstateList}/>

导入后的App.js中的错误apeares

Uncaught TypeError: Cannot call a class as a function