Bắt không thể gọi một lớp là một chức năng trong dự án React của tôi


129

Tôi đang cố gắng thêm một thành phần bản đồ React vào dự án của mình nhưng gặp lỗi. Tôi đang sử dụng bài đăng trên blog của Fullstack React làm tài liệu tham khảo. Tôi đã theo dõi nơi lỗi được ném trong dòng 83 của google_map.js:

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

Đây là thành phần bản đồ của tôi cho đến nay. Trang chỉ tải tốt (không có bản đồ) khi tôi nhận xét các dòng 58-60, ba dòng cuối cùng. chỉnh sửa: Tôi đã thực hiện các thay đổi mà @Dmitriy Nevzorov đề xuất và nó vẫn gây ra lỗi tương tự.

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)

Và đây là nơi thành phần bản đồ này được định tuyến trong 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
Bạn có hai export defaults, và nó sẽ new GoogleAPIComponent()không GoogleAPIComponent()?
gcampbell

Tôi đã xóa một trong những mặc định và thử đề xuất của bạn. Dường như nó thực sự đang nói chuyện với Google Maps hiện, đó là tốt, nhưng trước khi trang có thể tải nó ném một lỗi khó hiểu: Locations.js: 58 của router Lỗi Loại:.? (Giá trị trung gian) không phải là một chức năng" Bất cứ ý tưởng
Mike Fleming

1
Điều gì nếu bạn loại bỏ (LocationContainer)?
gcampbell

Cảm ơn, tôi nghĩ rằng đã có nó! Thật kỳ lạ, đó là cách họ viết nó trên bài đăng trên blog của họ. Vẫn nhận được một vài lỗi khác từ Google Maps, tôi sẽ đặt chúng ở đây: 'GoogleMap: apiKey không được dùng nữa, thay vào đó, hãy sử dụng bootstrapURLKeys = {{key: YOU_API_KEY}}. google_map.js: 689 GoogleMap: centre hoặc defaultCenterproperty phải được xác định google_map.js: 699 GoogleMap: zoom hoặc defaultZoomproperty phải được xác định google_map.js: 704 '
Mike Fleming

1
Tôi không chắc chắn về các lỗi khác, nhưng bạn có thể thử cách này để sửa lỗi đầu tiên:export default new GoogleApiComponent({ bootstrapURLKeys: MY_API_KEY })
gcampbell 20/07/2016

Câu trả lời:


206

Đối với tôi nó đã xảy ra khi tôi quên viết extends React.Componentở cuối. Tôi biết đó không chính xác là những gì BẠN đã có, nhưng những người khác đọc câu trả lời này có thể được hưởng lợi từ điều này, hy vọng.


19
Có bài đăng tuyệt vời khi phản ứng thái quá giải thích lý do tại sao điều này hoạt động quá
mức.io / how-does-react-a-class-from-a-hàm

1
Tóm tắt bài đăng: Phân biệt giữa một lớp và một chức năng trong trình duyệt thực sự không hoàn toàn tầm thường ... "Giải pháp thực tế rất đơn giản, nhưng [Tôi sẽ tiếp tục] giải thích tại sao React kết thúc với giải pháp này. .. "blah, blah, blah, ... ->" Nếu bạn không mở rộng React.Component, React sẽ không tìm thấy isReactComponent trên nguyên mẫu và sẽ không coi thành phần là một lớp. "
spinkus

69

Đối với tôi đó là vì tôi quên sử dụng newtừ khóa khi thiết lập trạng thái Hoạt hình.

ví dụ:

fadeAnim: Animated.Value(0),

đến

fadeAnim: new Animated.Value(0),

sẽ sửa nó


1
Điều này đã giải quyết vấn đề của tôi, tôi đã sử dụng một trường hợp sử dụng khác không phải hoạt hình nhưng sau khi sử dụng từ khóa mới đã giải quyết nó. Cảm ơn bạn
Olivier JM

2
Đã dành 4 giờ 44 phút và 4 giây cố gắng để biết wth đã xảy ra. Bạn là chúa
Sediteshwaran

Yup, đó cũng là tôi. Cảm ơn bạn!
James Cushing

64

tl; dr

Nếu bạn sử dụng React Router v4, hãy kiểm tra <Route/>thành phần của bạn nếu bạn thực sự sử dụng componentprop để vượt qua thành phần React dựa trên lớp của bạn!

Tổng quát hơn: Nếu lớp của bạn có vẻ ổn, hãy kiểm tra xem mã gọi nó không cố sử dụng nó làm hàm.

Giải trình

Tôi đã gặp lỗi này vì tôi đang sử dụng React Router v4 và tôi đã vô tình sử dụng renderprop thay vì componentmột trong <Route/>thành phần để vượt qua thành phần của tôi là một lớp. Đây là một vấn đề, bởi vì rendermong đợi (gọi) một chức năng, trong khi đó componentlà một chức năng sẽ hoạt động trên các thành phần React.

Vì vậy, trong mã này:

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

Dòng chứa <Route/>thành phần, nên được viết như thế này:

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

Thật là xấu hổ, họ không kiểm tra nó và đưa ra một lỗi có thể sử dụng cho lỗi đó và dễ bị bắt.


47

Đã xảy ra với tôi vì tôi đã sử dụng

PropTypes.arrayOf(SomeClass)

thay vì

PropTypes.arrayOf(PropTypes.instanceOf(SomeClass))


Cảm ơn, định nghĩa PropTypes sai là vấn đề trong trường hợp của tôi.
Vasiliy

Điều này đã giải quyết vấn đề của tôi! đã PropTypes.oneOfType([SomeClass, SomeOtherClass]).isRequired,thay vì PropTypes.oneOfType([PropTypes.instanceOf(SomeClass), PropTypes.instanceOf(SomeOtherClass)]).isRequired,
Doug

Cảm ơn, đã thực sự tự hỏi trong một thời gian dài những gì đã xảy ra ở đó!
Got The Fever Media

14

Bạn đã export defaultkhai báo trùng lặp . Cái đầu tiên bị ghi đè bởi cái thứ hai thực sự là một hàm.


Nắm bắt tốt! Tôi đã để mặc định trước GoogleApiComponent và tôi vẫn gặp lỗi tương tự. Ngoài ra, việc xóa tất cả các mặc định mang lại cho tôi lỗi "mã thông báo không mong muốn" trong thiết bị đầu cuối của tôi trên GoogleApiComponent.
Mike Fleming

14

Đối với tôi, nó đã ComponentName.prototypethay vì ComponentName.propTypes. tự động đề xuất bởi PhpstormIDE. Hy vọng nó sẽ giúp được ai đó.


14

Tôi đã trải qua vấn đề tương tự, nó xảy ra vì ES6lớp thành phần của tôi không mở rộng React.Component.


8

Hầu hết các vấn đề này xảy ra khi bạn bỏ lỡ Thành phần mở rộng từ phản ứng:

import React, {Component} from 'react'

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

7

Đối với tôi đó là vì tôi đã sử dụng nguyên mẫu thay vì propTypes

class MyComponent extends Component {

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

MyComponent.prototype = {

};

nó phải là

MyComponent.propTypes = {

};

Chính xác trường hợp tương tự cho tôi. Cảm ơn bạn!
Tekson

6
Post.proptypes = {

}

đến

Post.propTypes = {

}

ai đó nên bình luận về cách theo dõi lỗi như vậy một cách rất chính xác.


1
Tốt hơn là giải thích giải pháp / câu trả lời của bạn với một số thông tin chi tiết.
Dharmang

Yaah nó xảy ra, Bravo!
Mbanda

3

Có vẻ như không có trường hợp nào khi lỗi này xuất hiện.

Đã xảy ra với tôi khi tôi không khai báo hàm tạo trong thành phần đầy đủ.

class MyComponent extends Component {

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

thay vì

class MyComponent extends Component {

    constructor(props) {
        super(props);
    }

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

3

Hai điều bạn có thể kiểm tra là,

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

Slider.propTypes = {
    // accessibility: PropTypes.bool,
}
  • Đảm bảo rằng bạn mở rộng React.Component
  • Sử dụng propTypes thay vì nguyên mẫu (theo IDE intellisense)

nên là Slider.propTypes: {}
David Casanellas

2

Đây là một vấn đề chung và không xuất hiện trong một trường hợp duy nhất. Nhưng, vấn đề phổ biến trong tất cả các trường hợp là bạn quên importmột thành phần cụ thể (không quan trọng nếu đó là từ thư viện mà bạn đã cài đặt hoặc thành phần tùy chỉnh mà bạn đã tạo):

import {SomeClass} from 'some-library'

Khi bạn sử dụng nó sau này, mà không nhập nó, trình biên dịch nghĩ rằng đó là một hàm. Do đó, nó phá vỡ. Đây là một ví dụ phổ biến:

imports

...code...

và sau đó ở đâu đó bên trong mã của bạn

<Image {..some props} />

Nếu bạn quên nhập thành phần <Image />thì trình biên dịch sẽ không phàn nàn như đối với các lần nhập khác, nhưng sẽ bị hỏng khi đến mã của bạn.


1

Đối với tôi, đó là vì tôi đã vô tình xóa renderphương pháp của mình !

Tôi đã có một lớp học với một componentWillReceivePropsphương pháp mà tôi không cần nữa, ngay trước một renderphương pháp ngắn . Trong sự vội vàng của tôi loại bỏ nó, tôi cũng vô tình loại bỏ toàn bộ renderphương pháp.

Đây là một PAIN để theo dõi, vì tôi đã nhận được lỗi bảng điều khiển chỉ vào các bình luận trong các tệp hoàn toàn không liên quan là "nguồn" của vấn đề.


1

Tôi đã có một vấn đề tương tự tôi đã gọi phương thức kết xuất không chính xác

Đã xảy ra lỗi:

render = () => {
    ...
}

thay vì

chính xác:

render(){
    ...
}

1

Tôi đã có nó khi tôi làm như vậy:

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

chính xác:

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

hoặc là

const foo = ...
export default foo

1

Đối với tôi, điều đó xảy ra vì tôi đã không bọc đúng chức năng kết nối của mình và cố gắng xuất hai thành phần mặc định


1

Tôi đã gặp phải lỗi này khi tôi nhập sai lớp và chuyển đến cửa hàng sai trong khi sử dụng mobx trong Reac -igen.

Tôi gặp phải lỗi trong đoạn trích này:

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

@inject ("counter")
@Observer

Sau vài lần sửa như dưới đoạn trích. Tôi đã giải quyết vấn đề của mình như thế này.

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

@inject("counterStore")
@observer

Điều thực sự sai, tôi đã sử dụng lớp sai thay vì observertôi đã sử dụng Observervà thay vì counterStoretôi đã sử dụng counter. Tôi đã giải quyết vấn đề của mình như thế này.


1

Trong tập tin MyComponent.js

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

Tôi đặt một số chức năng liên quan đến thành phần đó:

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

export myFunction() {
...
}

và sau đó trong một tệp khác đã nhập chức năng đó:

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

Bạn có thể phát hiện ra vấn đề?

Tôi quên mất các dấu ngoặc nhọn, và nhập MyComponentdưới tên myFunction!

Vì vậy, cách khắc phục là:

import {myFunction} from './MyComponent'

1

Tôi đã trải nghiệm điều này khi viết một câu lệnh nhập sai trong khi nhập một hàm, thay vì một lớp. Nếu removeMateriallà một chức năng trong một mô-đun khác:

Đúng:

import { removeMaterial } from './ClaimForm';

Sai lầm:

import removeMaterial from './ClaimForm';

1

Tôi đã nhận được lỗi này bằng cách mắc lỗi nhỏ. Lỗi của tôi là xuất lớp dưới dạng hàm thay vì là lớp. Ở dưới cùng của tập tin lớp tôi đã có:

export default InputField();

khi nào nên có:

export default InputField;

0

Tôi cũng đã gặp phải điều này, có thể bạn có lỗi javascript bên trong thành phần phản ứng của bạn. Hãy chắc chắn nếu bạn đang sử dụng một phụ thuộc mà bạn đang sử dụng newtoán tử trên lớp để khởi tạo thể hiện mới. Lỗi sẽ ném nếu

this.classInstance = Class({})

thay vì sử dụng

this.classInstance = new Class({})

bạn sẽ thấy trong chuỗi lỗi trong trình duyệt

at ReactCompositeComponentWrapper._constructComponentWithoutOwner

đó là sự cho đi mà tôi tin


0

Hãy thử dừng HMR của bạn và nhấn npm startlại để xây dựng lại dự án của bạn.
Điều này, làm cho lỗi biến mất, không biết tại sao.


0

Trong trường hợp của tôi, tôi đã viết commentthay cho Componentsai lầm

Tôi chỉ viết này.

import React, { Component } from 'react';

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

Thay vì điều này.

import React, { Component } from 'react';

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

nó không phải là một vấn đề lớn nhưng đối với một người mới bắt đầu như tôi thì thật khó hiểu. Tôi hy vọng điều này sẽ hữu ích.


0

Trong trường hợp của tôi, sử dụng JSX, một thành phần cha mẹ đã gọi các thành phần khác mà không có "<>"

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

sửa chữa

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

0

Một báo cáo khác ở đây: Nó không hoạt động khi tôi xuất khẩu:

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

thay vì

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

Lưu ý vị trí của dấu ngoặc. Cả hai đều chính xác và sẽ không bị bắt bởi một kẻ nói dối hoặc xinh đẹp hơn hoặc một cái gì đó tương tự. Mất một lúc để theo dõi nó.


0

Trong trường hợp của tôi, tôi vô tình đặt tên thành phần ( Home) làm đối số đầu tiên connecthoạt động trong khi nó được cho là ở cuối. tât nhiên.

Điều này một cách an toàn - đã cho tôi lỗi:

export default connect(Home)(mapStateToProps, mapDispatchToProps)

Nhưng cái này hoạt động một cách an toàn - tốt:

export default connect(mapStateToProps, mapDispatchToProps)(Home)

0

Điều này xảy ra khi tôi vô tình đặt tên cho renderchức năng của mình không chính xác:

import React from 'react';

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

Trường hợp của tôi về lỗi này chỉ đơn giản là do lớp của tôi không có lỗi render phương thức .


0

Trên thực tế tất cả các vấn đề redux kết nối. các giải pháp:

Đúng :

export default connect(mapStateToProps, mapDispatchToProps)(PageName)

Sai & Lỗi :

export default connect(PageName)(mapStateToProps, mapDispatchToProps)

-1

Đối với tôi, đó là việc nhập sai bộ giảm tốc trong rootReducer.js. Tôi nhập container thay vì tập tin giảm.

Thí dụ

import settings from './pages/Settings';

Nhưng chắc chắn nó phải

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

Trong đó thư mục cài đặt chứa các tệp Action.js, index.js, lesser.js.

Để kiểm tra, bạn có thể đăng nhập bộ giảm tốc arg của hàm assertReducerShape () từ redux / es / redux.js.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.