Mendapatkan "Tidak dapat memanggil kelas sebagai fungsi" di Proyek Bereaksi saya

130

Saya mencoba menambahkan komponen Peta Bereaksi untuk proyek saya tetapi mengalami kesalahan. Saya menggunakan posting blog Fullstack React sebagai referensi. Saya melacak di mana kesalahan dilemparkan ke google_map.js baris 83:

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

Ini adalah komponen peta saya sejauh ini. Halaman dimuat dengan baik (tanpa peta) ketika saya mengomentari baris 58-60, tiga baris terakhir. sunting: Saya membuat perubahan yang disarankan @Dmitriy Nevzorov dan itu masih memberi saya kesalahan yang sama.

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)

Dan di sinilah komponen peta ini dialihkan ke 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'))
Mike Fleming
sumber
2
Anda punya dua export default, dan new GoogleAPIComponent()bukan GoogleAPIComponent()?
gcampbell
Saya menghapus salah satu default dan mencoba saran Anda. Sepertinya itu benar-benar berbicara dengan Google Maps sekarang, yang bagus, tetapi sebelum halaman dapat memuatnya melemparkan kesalahan kriptik lain: Locations.js: 58 Uncaught TypeError: (nilai menengah) bukan fungsi ". Ada ide?
Mike Fleming
1
Bagaimana jika Anda menghapusnya (LocationContainer)?
gcampbell
Terima kasih, saya pikir sudah mengerti! Aneh, begitulah cara mereka menulis di posting blog mereka. Masih mendapatkan beberapa kesalahan lain dari Google Maps, saya akan meletakkannya di sini: 'GoogleMap: apiKey sudah tidak digunakan lagi, gunakan bootstrapURLKeys = {{key: YOUR_API_KEY}} sebagai gantinya. google_map.js: 689 GoogleMap: center atau defaultCenterproperty harus didefinisikan google_map.js: 699 GoogleMap: zoom atau defaultZoomproperty harus didefinisikan google_map.js: 704 '
Mike Fleming
1
Saya tidak yakin tentang kesalahan lain, tetapi Anda bisa mencoba ini untuk memperbaiki yang pertama:export default new GoogleApiComponent({ bootstrapURLKeys: MY_API_KEY })
gcampbell

Jawaban:

207

Bagi saya itu terjadi ketika saya lupa menulis extends React.Componentdi akhir. Saya tahu itu bukan apa yang ANDA miliki, tetapi orang lain yang membaca jawaban ini dapat mengambil manfaat dari ini, semoga.

programmer
sumber
19
Ada pos bagus di reaksi berlebihan yang menjelaskan mengapa ini bekerja reaksi berlebihan.io/how-do-react-tell-a-class-from-a-function
Eric Kigathi
1
Ringkasan pos: Membedakan antara kelas dan fungsi di peramban sebenarnya tidak sepenuhnya sepele ... "Solusi sebenarnya sangat sederhana, tetapi [saya akan] bersinggungan besar untuk menjelaskan mengapa React berakhir dengan solusi ini. .. "bla, bla, bla, ... ->" Jika Anda tidak memperpanjang React.Component, React tidak akan menemukan adalahReactComponent pada prototipe, dan tidak akan memperlakukan komponen sebagai kelas. "
spinkus
Bagus. Saya menghadapi masalah serupa & solusi Anda memperbaiki masalah ini. Tetapi sintaks saya adalah import React, { Component } from 'react'; class extends Component. Saya tidak mengerti bagaimana cara mengatasi masalah ini dengan menggantinya Componentdengan React.Component. Apakah impor itu penting?
Arun Ramachandran
70

Bagi saya itu karena saya lupa menggunakan newkata kunci saat mengatur status Animasi.

misalnya:

fadeAnim: Animated.Value(0),

untuk

fadeAnim: new Animated.Value(0),

akan memperbaikinya.

William Park
sumber
1
Ini memecahkan masalah saya, saya menggunakan use case yang berbeda bukan animasi tetapi setelah menggunakan kata kunci baru menyelesaikannya. Terima kasih
Olivier JM
4
Menghabiskan 4 jam 44 menit dan 4 detik untuk mencoba mengetahui apa yang terjadi. Kamu adalah Tuhan.
Satheeshwaran
Yup, itu juga aku. Terima kasih!
James Cushing
64

tl; dr

Jika Anda menggunakan React Router v4 periksa <Route/>komponen Anda jika Anda memang menggunakan componentprop untuk melewati komponen Bereaksi berbasis kelas Anda!

Secara umum: Jika kelas Anda tampak ok, periksa apakah kode yang memanggilnya tidak mencoba menggunakannya sebagai fungsi.

Penjelasan

Saya mendapat kesalahan ini karena saya menggunakan React Router v4 dan saya tidak sengaja menggunakan renderprop bukan yang componentada di <Route/>komponen untuk melewati komponen saya yang merupakan kelas. Ini adalah masalah, karena rendermengharapkan (panggilan) suatu fungsi, sedangkan componentyang akan bekerja pada komponen Bereaksi.

Jadi dalam kode ini:

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

Baris yang berisi <Route/>komponen, seharusnya ditulis seperti ini:

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

Sangat memalukan, bahwa mereka tidak memeriksanya dan memberikan kesalahan yang dapat digunakan untuk kesalahan tersebut dan mudah ditangkap.

totymedli
sumber
47

Terjadi pada saya karena saya dulu

PropTypes.arrayOf(SomeClass)

dari pada

PropTypes.arrayOf(PropTypes.instanceOf(SomeClass))

Dan Balaban
sumber
Terima kasih, definisi PropTypes yang salah adalah masalah dalam kasus saya.
Vasiliy
ini memecahkan masalah saya! adalah PropTypes.oneOfType([SomeClass, SomeOtherClass]).isRequired,bukan PropTypes.oneOfType([PropTypes.instanceOf(SomeClass), PropTypes.instanceOf(SomeOtherClass)]).isRequired,
Doug
Terima kasih, sudah lama bertanya-tanya apa yang salah di sana!
Got The Fever Media
14

Anda memiliki duplikat export defaultdeklarasi. Yang pertama dikesampingkan oleh yang kedua yang sebenarnya merupakan fungsi.

Dmitriy Nevzorov
sumber
Tangkapan yang bagus! Saya meninggalkan default di depan GoogleApiComponent dan saya masih mendapatkan kesalahan yang sama. Atau, menghapus semua default memberi saya kesalahan "tak terduga" di terminal saya di GoogleApiComponent.
Mike Fleming
14

Bagi saya, itu ComponentName.prototypebukan ComponentName.propTypes. otomatis disarankan oleh PhpstormIDE. Semoga ini bisa membantu seseorang.

codersaif
sumber
14

Saya mengalami masalah yang sama, itu terjadi karena ES6kelas komponen saya tidak meluas React.Component.

Selai
sumber
8

Sebagian besar masalah ini terjadi ketika Anda tidak dapat memperluas Komponen dari reaksi:

import React, {Component} from 'react'

export default class TimePicker extends Component {
    render() {
        return();     
    }
}
jeff ayan
sumber
7

Bagi saya itu karena saya menggunakan prototipe alih-alih propTip

class MyComponent extends Component {

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

MyComponent.prototype = {

};

seharusnya begitu

MyComponent.propTypes = {

};
Onengiye Richard
sumber
Kasus yang sama persis untuk saya. Terima kasih!
Tekson
6
Post.proptypes = {

}

untuk

Post.propTypes = {

}

seseorang harus mengomentari cara memantau kesalahan semacam itu dengan cara yang sangat tepat.

Mbanda
sumber
1
Lebih baik menjelaskan solusi / jawaban Anda dengan beberapa informasi terperinci.
Dharmang
Yaah itu terjadi, Bravo!
Mbanda
3

Sepertinya tidak ada kasus tunggal saat kesalahan ini muncul.

Terjadi pada saya ketika saya tidak mendeklarasikan konstruktor dalam komponen statefull.

class MyComponent extends Component {

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

dari pada

class MyComponent extends Component {

    constructor(props) {
        super(props);
    }

    render() {
        return <div>Test</div>;
    }
}
Pavel Kozlov
sumber
3

Dua hal yang dapat Anda periksa adalah,

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

Slider.propTypes = {
    // accessibility: PropTypes.bool,
}
  • Pastikan Anda meluas React.Component
  • Gunakan propTypes alih-alih prototipe (sesuai IDE intellisense)
Dipen Dedania
sumber
seharusnya menjadi Slider.propTypes: {}
David Casanellas
2

Ini adalah masalah umum, dan tidak muncul dalam satu kasus. Namun, masalah umum dalam semua kasus adalah Anda lupa importkomponen tertentu (tidak masalah apakah itu dari perpustakaan yang Anda instal atau komponen yang dibuat khusus yang Anda buat):

import {SomeClass} from 'some-library'

Ketika Anda menggunakannya nanti, tanpa mengimpornya, kompiler berpikir itu adalah fungsi. Karena itu rusak. Ini adalah contoh umum:

imports

...code...

dan kemudian di suatu tempat di dalam kode Anda

<Image {..some props} />

Jika Anda lupa mengimpor komponen <Image />maka kompiler tidak akan mengeluh seperti itu untuk impor lainnya, tetapi akan rusak ketika mencapai kode Anda.

Tim G. Pegas
sumber
1

Bagi saya, itu karena saya tidak sengaja menghapus rendermetode saya !

Saya memiliki kelas dengan componentWillReceivePropsmetode yang tidak saya butuhkan lagi, segera sebelum rendermetode singkat . Dengan tergesa-gesa menghapusnya, saya tidak sengaja menghapus seluruh rendermetode juga.

Ini adalah NYERI untuk dilacak, karena saya mendapatkan kesalahan konsol yang menunjuk pada komentar dalam file yang sama sekali tidak relevan sebagai "sumber" masalah.

Alex McMillan
sumber
1

Saya memiliki masalah yang sama ketika saya memanggil metode render secara salah

Memberi kesalahan:

render = () => {
    ...
}

dari pada

benar:

render(){
    ...
}
Emile Esterhuizen
sumber
1

Saya memilikinya ketika saya melakukannya:

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

benar:

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

atau

const foo = ...
export default foo
Jeka Yaroshenko
sumber
1

Bagi saya itu terjadi karena saya tidak membungkus fungsi koneksi saya dengan benar, dan mencoba untuk mengekspor dua komponen default

Dmitriy
sumber
1

Saya menghadapi kesalahan ini ketika saya mengimpor kelas yang salah dan merujuk ke toko yang salah saat menggunakan mobx di reaksi-asli.

Saya menghadapi kesalahan dalam cuplikan ini:

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

@inject ("counter")
@Observer

Setelah beberapa koreksi seperti cuplikan di bawah ini. Saya menyelesaikan masalah saya seperti ini.

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

@inject("counterStore")
@observer

Apa yang sebenarnya salah, saya menggunakan kelas yang salah alih-alih observersaya gunakan Observerdan bukannya counterStoresaya gunakan counter. Saya memecahkan masalah saya seperti ini.

badarshahzad
sumber
1

Dalam file MyComponent.js

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

Saya menaruh beberapa fungsi yang terkait dengan komponen itu:

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

export myFunction() {
...
}

dan kemudian di file lain yang diimpor fungsi itu:

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

Bisakah Anda menemukan masalahnya?

Saya lupa kawat gigi keriting, dan diimpor MyComponentdengan nama myFunction!

Jadi, perbaikannya adalah:

import {myFunction} from './MyComponent'
Mikhail Vasin
sumber
1

Saya mengalami ini ketika menulis pernyataan impor yang salah saat mengimpor fungsi, bukan kelas. Jika removeMaterialada fungsi dalam modul lain:

Baik:

import { removeMaterial } from './ClaimForm';

Salah:

import removeMaterial from './ClaimForm';
shacker
sumber
1

Saya menerima kesalahan ini dengan membuat kesalahan kecil. Kesalahan saya adalah mengekspor kelas sebagai fungsi, bukan sebagai kelas. Di bagian bawah file kelas saya, saya punya:

export default InputField();

padahal seharusnya:

export default InputField;
airvine
sumber
0

Saya juga mengalami hal ini, ada kemungkinan Anda memiliki kesalahan javascript di dalam komponen reaksi Anda. Pastikan jika Anda menggunakan dependensi Anda menggunakan newoperator di kelas untuk instantiate instance baru. Kesalahan akan muncul jika

this.classInstance = Class({})

alih-alih gunakan

this.classInstance = new Class({})

Anda akan melihat di rantai kesalahan di browser

at ReactCompositeComponentWrapper._constructComponentWithoutOwner

itu adalah hadiah yang saya percaya.

mibbit
sumber
0

Coba hentikan HMR Anda dan tekan npm startlagi untuk membangun kembali proyek Anda.
Ini, membuat kesalahan menghilang, tidak tahu mengapa.

Alexander Gorelik
sumber
0

Dalam kasus saya, saya menulis commentdi tempat Componentkarena kesalahan

Saya baru saja menulis ini.

import React, { Component } from 'react';

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

Alih-alih ini.

import React, { Component } from 'react';

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

ini bukan masalah besar tapi bagi pemula seperti saya ini benar-benar membingungkan. Saya harap ini akan membantu.

Uddesh_jain
sumber
0

Dalam kasus saya, menggunakan JSX komponen induk memanggil komponen lain tanpa "<>"

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

memperbaiki

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

Laporan lain di sini: Tidak berfungsi saat saya mengekspor:

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

dari pada

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

Perhatikan posisi kurung. Keduanya benar dan tidak akan ketahuan oleh seorang linter atau lebih cantik atau sesuatu yang serupa. Butuh waktu beberapa saat untuk melacaknya.

Sebastijan Dumančić
sumber
0

Dalam kasus saya, saya secara tidak sengaja menempatkan nama komponen ( Home) sebagai argumen pertama yang connectberfungsi saat seharusnya di bagian akhir. ya

Yang satu ini - benar-benar memberi saya kesalahan:

export default connect(Home)(mapStateToProps, mapDispatchToProps)

Tapi yang ini bekerja dengan baik-baik saja:

export default connect(mapStateToProps, mapDispatchToProps)(Home)
scaryguy
sumber
0

Ini terjadi ketika saya secara tidak sengaja menyebutkan renderfungsi saya secara tidak benar:

import React from 'react';

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

Contoh kesalahan saya ini hanya disebabkan karena kelas saya tidak memiliki rendermetode yang tepat .

Bryan Bor
sumber
0

Sebenarnya semua masalah redux terhubung. solusi:

Benar :

export default connect(mapStateToProps, mapDispatchToProps)(PageName)

Salah & Bug :

export default connect(PageName)(mapStateToProps, mapDispatchToProps)
Batuhan Orhan
sumber
-1

Bagi saya itu salah impor reducer di rootReducer.js. Saya mengimpor kontainer alih-alih file peredam.

Contoh

import settings from './pages/Settings';

Tapi tentu harus begitu

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

Di mana direktori pengaturan berisi file-file berikut action.js, index.js, reducer.js.

Untuk memeriksanya, Anda dapat mencatat arg reduksi dari fungsi assertReducerShape () dari redux / es / redux.js.

Oleg Shishkov
sumber