In meinem React Project wird "Klasse kann nicht als Funktion aufgerufen werden" angezeigt

128

Ich versuche, meinem Projekt eine React Map-Komponente hinzuzufügen, aber es tritt ein Fehler auf. Ich verwende den Blog-Beitrag von Fullstack React als Referenz. Ich habe in google_map.js Zeile 83 herausgefunden, wo der Fehler ausgelöst wird:

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

Hier ist meine bisherige Kartenkomponente. Die Seite wird einwandfrei geladen (ohne Karte), wenn ich die Zeilen 58-60, die letzten drei Zeilen, auskommentiere. Bearbeiten: Ich habe die von @Dmitriy Nevzorov vorgeschlagenen Änderungen vorgenommen und es gibt mir immer noch den gleichen Fehler.

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)

Und hier wird diese Kartenkomponente in main.js geroutet:

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
quelle
2
Sie haben zwei export defaults, und wäre es new GoogleAPIComponent()nicht GoogleAPIComponent()?
Gcampbell
Ich habe eine der Standardeinstellungen entfernt und Ihren Vorschlag ausprobiert. Es sieht so aus, als würde es jetzt tatsächlich mit Google Maps sprechen, was gut ist, aber bevor die Seite geladen werden kann, wird ein weiterer kryptischer Fehler ausgegeben: Locations.js: 58 Uncught TypeError: (Zwischenwert) ist keine Funktion ". Irgendwelche Ideen?
Mike Fleming
1
Was ist, wenn Sie das entfernen (LocationContainer)?
Gcampbell
Danke, ich denke das hat es geschafft! Seltsam, so haben sie es in ihrem Blog-Beitrag geschrieben. Ich erhalte noch einige andere Fehler von Google Maps und werde sie hier einfügen: 'GoogleMap: apiKey ist veraltet. Verwenden Sie stattdessen bootstrapURLKeys = {{key: YOUR_API_KEY}}. google_map.js: 689 GoogleMap: center oder defaultCenterproperty muss definiert werden google_map.js: 699 GoogleMap: zoom oder defaultZoomproperty muss definiert werden google_map.js: 704 '
Mike Fleming
1
Ich bin mir nicht sicher über die anderen Fehler, aber Sie könnten dies versuchen, um den ersten zu beheben:export default new GoogleApiComponent({ bootstrapURLKeys: MY_API_KEY })
gcampbell

Antworten:

206

Für mich passierte es, als ich extends React.Componentam Ende vergaß zu schreiben . Ich weiß, dass es nicht genau das ist, was SIE hatten, aber andere, die diese Antwort lesen, können hoffentlich davon profitieren.

Programmierer
quelle
19
Es gibt großen Beitrag zu heftig reagiert , die erklärt , warum das funktioniert overreacted.io/how-does-react-tell-a-class-from-a-function
Eric Kigathi
1
Zusammenfassung des Beitrags: Die Unterscheidung zwischen einer Klasse und einer Funktion im Browser ist eigentlich nicht ganz trivial ... "Die eigentliche Lösung ist wirklich einfach, aber [ich gehe auf eine] große Tangente, um zu erklären, warum React zu dieser Lösung kam. .. "bla, bla, bla, ... ->" Wenn Sie React.Component nicht erweitern, findet React isReactComponent im Prototyp nicht und behandelt Komponente nicht als Klasse. "
Spinkus
69

Für mich war es, weil ich vergessen habe, das newSchlüsselwort beim Einrichten des animierten Status zu verwenden.

z.B:

fadeAnim: Animated.Value(0),

zu

fadeAnim: new Animated.Value(0),

würde es reparieren.

William Park
quelle
1
Dies löste mein Problem, ich verwendete einen anderen Anwendungsfall, nicht den animierten, aber nachdem ich das neue Schlüsselwort verwendet hatte, löste ich es. Vielen Dank
Olivier JM
2
Verbrachte 4 Stunden 44 Minuten und 4 Sekunden damit, zu wissen, was passiert ist. Du bist Gott.
Satheeshwaran
Ja, das war ich auch. Danke dir!
James Cushing
64

tl; dr

Wenn Sie React Router v4 verwenden, überprüfen Sie Ihre <Route/>Komponente, ob Sie tatsächlich die componentRequisite verwenden, um Ihre klassenbasierte React-Komponente zu bestehen!

Allgemeiner: Wenn Ihre Klasse in Ordnung zu sein scheint, überprüfen Sie, ob der Code, der sie aufruft, nicht versucht, sie als Funktion zu verwenden.

Erläuterung

Ich habe diesen Fehler erhalten, weil ich React Router v4 verwendet habe und versehentlich die renderRequisite anstelle der Requisite componentin der <Route/>Komponente verwendet habe, um meine Komponente zu übergeben, die eine Klasse war. Dies war ein Problem, da rendereine Funktion erwartet (aufgerufen) wird, während sie componentfür React-Komponenten funktioniert.

Also in diesem Code:

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

Die Zeile mit der <Route/>Komponente sollte folgendermaßen geschrieben sein:

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

Es ist eine Schande, dass sie es nicht überprüfen und einen brauchbaren Fehler für einen solchen und leicht zu fassenden Fehler geben.

totymedli
quelle
47

Ist mir passiert, weil ich es benutzt habe

PropTypes.arrayOf(SomeClass)

anstatt

PropTypes.arrayOf(PropTypes.instanceOf(SomeClass))

Dan Balaban
quelle
Vielen Dank, in meinem Fall war die falsche PropTypes-Definition das Problem.
Vasiliy
das hat mein Problem gelöst! war PropTypes.oneOfType([SomeClass, SomeOtherClass]).isRequired,statt PropTypes.oneOfType([PropTypes.instanceOf(SomeClass), PropTypes.instanceOf(SomeOtherClass)]).isRequired,
Doug
Danke, habe mich lange gefragt, was dort falsch gelaufen ist!
Got The Fever Media
14

Sie haben die export defaultErklärung dupliziert . Der erste wird vom zweiten überschrieben, was eigentlich eine Funktion ist.

Dmitriy Nevzorov
quelle
Guter Fang! Ich habe die Standardeinstellung vor GoogleApiComponent belassen und erhalte immer noch den gleichen Fehler. Wenn Sie alternativ alle Standardeinstellungen entfernen, wird in meinem Terminal in GoogleApiComponent ein "unerwarteter Token" -Fehler angezeigt.
Mike Fleming
14

Für mich war es ComponentName.prototypestatt ComponentName.propTypes. automatisch von PhpstormIDE vorgeschlagen. Hoffe es wird jemandem helfen.

codersaif
quelle
14

Ich hatte das gleiche Problem, es trat auf, weil meine ES6Komponentenklasse nicht erweitert wurde React.Component.

Marmelade
quelle
8

Meistens treten diese Probleme auf, wenn Sie die Erweiterung der Komponente von "Reagieren" verpassen :

import React, {Component} from 'react'

export default class TimePicker extends Component {
    render() {
        return();     
    }
}
Jeff Ayan
quelle
7

Für mich war es, weil ich Prototypen anstelle von PropTypes verwendet habe

class MyComponent extends Component {

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

MyComponent.prototype = {

};

es sollte sein

MyComponent.propTypes = {

};
Onengiye Richard
quelle
Genau der gleiche Fall für mich. Danke dir!
Tekson
6
Post.proptypes = {

}

zu

Post.propTypes = {

}

Jemand sollte kommentieren, wie ein solcher Fehler sehr genau überwacht werden kann.

Mbanda
quelle
1
Es ist besser, Ihre Lösung / Antwort mit einigen detaillierten Informationen zu erklären.
Dharmang
Ja, es passiert, Bravo!
Mbanda
3

Es sieht so aus, als gäbe es keinen Einzelfall, wenn dieser Fehler auftritt.

Ist mir passiert, als ich den Konstruktor nicht in der Statefull-Komponente deklariert habe.

class MyComponent extends Component {

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

anstatt

class MyComponent extends Component {

    constructor(props) {
        super(props);
    }

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

Zwei Dinge, die Sie überprüfen können, sind:

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

Slider.propTypes = {
    // accessibility: PropTypes.bool,
}
  • Stellen Sie sicher, dass Sie React.Component erweitern
  • Verwenden Sie propTypes anstelle des Prototyps (gemäß IDE Intellisense).
Dipen Dedania
quelle
sollte Slider.propTypes sein: {}
David Casanellas
2

Dies ist ein allgemeines Problem und tritt nicht in einem Einzelfall auf. Das häufigste Problem in allen Fällen ist jedoch, dass Sie importeine bestimmte Komponente vergessen (unabhängig davon, ob sie aus einer von Ihnen installierten Bibliothek oder einer von Ihnen erstellten benutzerdefinierten Komponente stammt):

import {SomeClass} from 'some-library'

Wenn Sie es später verwenden, ohne es zu importieren, hält der Compiler es für eine Funktion. Daher bricht es. Dies ist ein häufiges Beispiel:

imports

...code...

und dann irgendwo in Ihrem Code

<Image {..some props} />

Wenn Sie vergessen haben, die Komponente zu importieren, <Image />beschwert sich der Compiler nicht wie bei anderen Importen, sondern bricht ab, wenn er Ihren Code erreicht.

Tim G. Pegas
quelle
1

Für mich war es, weil ich meine renderMethode versehentlich gelöscht hatte !

Ich hatte eine Klasse mit einer componentWillReceivePropsMethode, die ich nicht mehr brauchte, unmittelbar vor einer kurzen renderMethode. In meiner Eile habe ich versehentlich auch die gesamte renderMethode entfernt .

Dies war ein Schmerz , den man aufspüren musste, da ich Konsolenfehler bekam, die auf Kommentare in völlig irrelevanten Dateien als "Quelle" des Problems hinwiesen.

Alex McMillan
quelle
1

Ich hatte ein ähnliches Problem, als ich die Rendermethode falsch aufrief

Hat einen Fehler gemacht:

render = () => {
    ...
}

anstatt

richtig:

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

Ich hatte es, als ich es tat:

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

korrekt:

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

oder

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

Bei mir ist es passiert, weil ich meine Verbindungsfunktion nicht richtig verpackt und versucht habe, zwei Standardkomponenten zu exportieren

Dmitriy
quelle
1

Ich habe diesen Fehler festgestellt, als ich die falsche Klasse importiert und auf den falschen Speicher verwiesen habe, während ich mobx in react-native verwendet habe.

In diesem Ausschnitt ist ein Fehler aufgetreten:

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

@inject ("counter")
@Observer

Nach wenigen Korrekturen wie im folgenden Ausschnitt. Ich habe mein Problem so gelöst.

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

@inject("counterStore")
@observer

Was eigentlich falsch war, ich benutzte die falsche Klasse anstatt observerich benutzte Observerund anstatt counterStoreich benutzte counter. Ich habe mein Problem so gelöst.

badarshahzad
quelle
1

Im Ordner MyComponent.js

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

Ich habe einige Funktionen in Bezug auf diese Komponente eingefügt:

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

export myFunction() {
...
}

und dann in eine andere Datei importiert diese Funktion:

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

Können Sie das Problem erkennen?

Ich habe die geschweiften Klammern vergessen und MyComponentunter Namen importiert myFunction!

Das Update war also:

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

Ich habe dies erlebt, als ich beim Importieren einer Funktion und nicht einer Klasse eine falsche Importanweisung geschrieben habe. Wenn removeMaterialist eine Funktion in einem anderen Modul:

Richtig:

import { removeMaterial } from './ClaimForm';

Falsch:

import removeMaterial from './ClaimForm';
Shacker
quelle
1

Ich habe diesen Fehler durch einen kleinen Fehler erhalten. Mein Fehler war das Exportieren der Klasse als Funktion anstatt als Klasse. Am Ende meiner Klassendatei hatte ich:

export default InputField();

wann es hätte sein sollen:

export default InputField;
Luftrebe
quelle
0

Ich bin auch darauf gestoßen, es ist möglich, dass Sie einen Javascript-Fehler in Ihrer Reaktionskomponente haben. Stellen Sie sicher, dass Sie bei Verwendung einer Abhängigkeit den newOperator für die Klasse verwenden, um die neue Instanz zu instanziieren. Fehler wird wenn werfen

this.classInstance = Class({})

stattdessen verwenden

this.classInstance = new Class({})

Sie sehen in der Fehlerkette im Browser

at ReactCompositeComponentWrapper._constructComponentWithoutOwner

Das ist das Werbegeschenk, glaube ich.

Mibbit
quelle
0

Versuchen Sie, Ihr HMR zu stoppen, und drücken Sie npm starterneut, um Ihr Projekt neu zu erstellen.
Dies ließ den Fehler verschwinden, weiß nicht warum.

Alexander Gorelik
quelle
0

In meinem Fall habe ich versehentlich commentanstelle Componentvon geschrieben

Ich habe das gerade geschrieben.

import React, { Component } from 'react';

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

An Stelle von.

import React, { Component } from 'react';

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

Es ist keine große Sache, aber für einen Anfänger wie mich ist es wirklich verwirrend. Ich hoffe das wird hilfreich sein.

Uddesh_jain
quelle
0

In meinem Fall hat eine übergeordnete Komponente bei Verwendung von JSX andere Komponenten ohne "<>" aufgerufen.

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

Fix

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

Ein weiterer Bericht hier: Es hat nicht funktioniert, als ich exportiert habe:

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

anstatt

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

Beachten Sie die Position der Klammern. Beide sind korrekt und werden weder von einem Linter noch von einem hübscheren oder ähnlichem erwischt. Ich habe eine Weile gebraucht, um es aufzuspüren.

Sebastijan Dumančić
quelle
0

In meinem Fall habe ich versehentlich den Komponentennamen ( Home) als erstes Argument angegeben, das connectfunktioniert, während es am Ende stehen sollte. duh.

Dieser gab mir sicher den Fehler:

export default connect(Home)(mapStateToProps, mapDispatchToProps)

Aber dieser hat sicher gut funktioniert:

export default connect(mapStateToProps, mapDispatchToProps)(Home)
Scaryguy
quelle
0

Dies geschah, als ich meine renderFunktion versehentlich falsch benannte:

import React from 'react';

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

Meine Instanz dieses Fehlers wurde einfach verursacht, weil meine Klasse keine richtige renderMethode hatte.

Bryan Bor
quelle
0

Eigentlich verbinden sich alle Probleme mit Redux. Lösungen:

Richtig :

export default connect(mapStateToProps, mapDispatchToProps)(PageName)

Falsch & Bug :

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

Für mich war es ein falscher Import eines Reduzierers in die Datei rootReducer.js. Ich habe Container anstelle von Reduzierungsdatei importiert.

Beispiel

import settings from './pages/Settings';

Aber sicher sollte es sein

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

Wobei das Einstellungsverzeichnis die folgenden Dateien enthält: action.js, index.js, reducer.js.

Um dies zu überprüfen, können Sie die Reduzierungen arg der Funktion assertReducerShape () aus der Datei redux / es / redux.js protokollieren.

Oleg Shishkov
quelle