【问题标题】:Getting "Cannot call a class as a function" in my React Project在我的 React 项目中获取“无法将类作为函数调用”
【发布时间】:2016-11-23 17:24:39
【问题描述】:

我正在尝试将 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'))

【问题讨论】:

  • 你有两个export defaults,是new GoogleAPIComponent()而不是GoogleAPIComponent()
  • 我删除了其中一项默认设置并尝试了您的建议。看起来它现在实际上正在与谷歌地图交谈,这很好,但在页面加载之前它会引发另一个神秘错误:Locations.js:58 Uncaught TypeError: (intermediate value) is not a function”。有什么想法吗?
  • 如果删除(LocationContainer)会怎样?
  • 谢谢,我想明白了!奇怪,这就是他们在博客文章上写的方式。仍然从 Google 地图中收到一些其他错误,我将它们放在这里:'GoogleMap: apiKey 已弃用,请改用 bootstrapURLKeys={{key: YOUR_API_KEY}}。 google_map.js:689 GoogleMap: center 或 defaultCenterproperty 必须定义 google_map.js:699 GoogleMap: zoom 或 defaultZoomproperty 必须定义 google_map.js: 704'
  • 我不确定其他错误,但您可以尝试修复第一个错误:export default new GoogleApiComponent({ bootstrapURLKeys: MY_API_KEY })

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


【解决方案1】:

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

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;

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

【讨论】:

    【解决方案2】:

    您可以检查两件事,

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

    【讨论】:

    • 应该是 Slider.propTypes: { }
    【解决方案3】:

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

    export default InputField();
    

    应该是什么时候:

    export default InputField;
    

    【讨论】:

      【解决方案4】:

      其实redux connect的所有问题。解决方案:

      正确

      export default connect(mapStateToProps, mapDispatchToProps)(PageName)
      

      错误和错误

      export default connect(PageName)(mapStateToProps, mapDispatchToProps)
      

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

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

          【讨论】:

          • 是的,这发生在我身上
          【解决方案7】:

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

          import {SomeClass} from 'some-library'

          当你稍后使用它时,没有导入它,编译器认为它是一个函数。因此,它会破裂。这是一个常见的例子:

          imports

          ...code...

          然后在你的代码中的某个地方

          &lt;Image {..some props} /&gt;

          如果您忘记导入组件 &lt;Image /&gt;,那么编译器不会像其他导入那样抱怨,而是会在到达您的代码时中断。

          【讨论】:

            【解决方案8】:

            当我不小心错误地命名了我的 render 函数时发生了这种情况:

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

            我的这个错误实例仅仅是因为我的类没有正确的render 方法。

            【讨论】:

              【解决方案9】:
              Post.proptypes = {
              
              }
              

              Post.propTypes = {
              
              }
              

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

              【讨论】:

              • 最好用一些详细的信息来解释你的解决方案/答案。
              • 是啊,它发生了,太棒了!
              【解决方案10】:

              在我的例子中,我不小心将组件名称 (Home) 作为 connect 函数的第一个参数,而它应该放在末尾。呵呵。

              这个 - 肯定 - 给了我错误:

              export default connect(Home)(mapStateToProps, mapDispatchToProps)
              

              但是这个工作-肯定-很好:

              export default connect(mapStateToProps, mapDispatchToProps)(Home)
              

              【讨论】:

                【解决方案11】:

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

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

                而不是

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

                注意括号的位置。两者都是正确的,不会被 linter 或 prettier 或类似的东西抓住。我花了一段时间才找到它。

                【讨论】:

                  【解决方案12】:

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

                  class MyComponent extends Component {
                  
                   render() {
                      return <div>Test</div>;
                    }
                  }
                  
                  MyComponent.prototype = {
                  
                  };
                  

                  应该是的

                  MyComponent.propTypes = {
                  
                  };
                  

                  【讨论】:

                  • 对我来说完全一样的情况。谢谢!
                  【解决方案13】:

                  在我的例子中,使用 JSX 父组件调用其他没有“”的组件

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

                  修复

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

                  【讨论】:

                    【解决方案14】:

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

                    对:

                    import { removeMaterial } from './ClaimForm';
                    

                    错误:

                    import removeMaterial from './ClaimForm';
                    

                    【讨论】:

                      【解决方案15】:

                      在文件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"
                      ...
                      

                      你能发现问题吗?

                      我忘记了花括号,并在名称myFunction 下导入了MyComponent

                      所以,解决方法是:

                      import {myFunction} from './MyComponent'
                      

                      【讨论】:

                        【解决方案16】:

                        就我而言,我错误地写了comment 代替Component

                        我刚刚写了这个。

                        import React, { Component } from 'react';
                        
                          class Something extends Component{
                              render() {
                                  return();
                             }
                          }
                        

                        而不是这个。

                        import React, { Component } from 'react';
                        
                          class Something extends comment{
                              render() {
                                  return();
                             }
                          }
                        

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

                        【讨论】:

                          【解决方案17】:

                          对我来说,在 rootReducer.js 中导入减速器是错误的。我导入了容器而不是减速器文件。

                          例子

                          import settings from './pages/Settings';
                          

                          当然应该是的

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

                          其中设置目录包含以下文件actions.js、index.js、reducer.js。

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

                          【讨论】:

                            【解决方案18】:

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

                            我在这个 sn-p 中遇到了错误:

                            import { inject, Observer } from "mobx-react";
                            
                            @inject ("counter")
                            @Observer
                            

                            经过几次修正,如下面的 sn-p。我就是这样解决了我的问题。

                            import { inject, observer } from "mobx-react";
                            
                            @inject("counterStore")
                            @observer
                            

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

                            【讨论】:

                              【解决方案19】:

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

                              【讨论】:

                              • overreacted 上有一篇很棒的帖子解释了为什么会这样overreacted.io/how-does-react-tell-a-class-from-a-function
                              • 帖子总结:在浏览器中区分一个类和一个函数其实并不完全是微不足道的......“实际的解决方案真的很简单,但是[我要去一个]巨大的切线来解释为什么 React 最终得到了这个解决方案......” blah, blah, blah, ... -> “如果你不扩展 React.Component,React 将不会在原型上找到 isReactComponent,并且不会将组件视为一堂课。”
                              • 太棒了。我遇到了类似的问题,您的解决方案解决了这个问题。但我的语法是import React, { Component } from 'react'; class extends Component。我无法理解如何通过将Component 替换为React.Component 来解决问题。进口重要吗?
                              【解决方案20】:

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

                              【讨论】:

                                【解决方案21】:

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

                                【讨论】:

                                  【解决方案22】:

                                  当我这样做的时候我得到了它:

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

                                  正确:

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

                                  const foo = ...
                                  export default foo
                                  

                                  【讨论】:

                                    【解决方案23】:

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

                                    所以不要这样:

                                    module.exports = MyClass;
                                    

                                    这样做:

                                    module.exports.MyClass = MyClass;
                                    

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

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

                                    这样您就不会导出函数。阅读更多here

                                    【讨论】:

                                      【解决方案24】:

                                      当您错过从 react 扩展 Component 时,通常会出现这些问题:

                                      import React, {Component} from 'react'
                                      
                                      export default class TimePicker extends Component {
                                          render() {
                                              return();     
                                          }
                                      }
                                      

                                      【讨论】:

                                        【解决方案25】:

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

                                        例如:

                                        fadeAnim: Animated.Value(0),

                                        fadeAnim: new Animated.Value(0),

                                        会解决的。

                                        【讨论】:

                                        • 这解决了我的问题,我使用的是不同的用例而不是动画,但在使用 new 关键字后解决了它。谢谢
                                        • 花了 4 小时 44 分 4 秒试图知道发生了什么。你是上帝。
                                        • 是的,我也是。谢谢!
                                        • 有人知道它更改了哪个版本吗? (RN需要担心的另一件事)
                                        • @AkinWilliams 我是来自未来的你。我及时回到过去,把你从这种痛苦中解救出来。
                                        【解决方案26】:

                                        我有一个类似的问题,我错误地调用了渲染方法

                                        报错:

                                        render = () => {
                                            ...
                                        }
                                        

                                        而不是

                                        正确:

                                        render(){
                                            ...
                                        }
                                        

                                        【讨论】:

                                          【解决方案27】:

                                          我也遇到过这个问题,你的 react 组件中可能有 javascript 错误。确保如果您使用的是依赖项,则您在类上使用 new 运算符来实例化新实例。如果

                                          this.classInstance = Class({})

                                          改为使用

                                          this.classInstance = new Class({})

                                          你会在浏览器的错误链中看到

                                          at ReactCompositeComponentWrapper._constructComponentWithoutOwner

                                          这是我相信的赠品。

                                          【讨论】:

                                            【解决方案28】:

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

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

                                            class MyComponent extends Component {
                                            
                                                render() {
                                                    return <div>Test</div>;
                                                }
                                            }
                                            

                                            而不是

                                            class MyComponent extends Component {
                                            
                                                constructor(props) {
                                                    super(props);
                                                }
                                            
                                                render() {
                                                    return <div>Test</div>;
                                                }
                                            }
                                            

                                            【讨论】:

                                              【解决方案29】:

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

                                              我有一个带有 componentWillReceiveProps 方法的类,我不再需要它,紧接在一个简短的 render 方法之前。在我匆忙删除它时,我不小心也删除了整个 render 方法。

                                              这是一个需要追查的PAIN,因为我收到控制台错误,指向完全不相关文件中的 cmets 作为问题的“根源”。

                                              【讨论】:

                                                【解决方案30】:

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

                                                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 出现错误

                                                Uncaught TypeError: Cannot call a class as a function
                                                

                                                【讨论】:

                                                  猜你喜欢
                                                  • 2018-10-21
                                                  • 1970-01-01
                                                  • 2016-12-25
                                                  • 2020-02-11
                                                  • 1970-01-01
                                                  • 1970-01-01
                                                  • 2020-03-12
                                                  • 1970-01-01
                                                  • 2018-04-30
                                                  相关资源
                                                  最近更新 更多