React Projemde "İşlev olarak bir sınıf çağrılamıyor" mesajı alınıyor


130

Projeme bir React harita bileşeni eklemeye çalışıyorum ancak bir hatayla karşılaşıyorum. Fullstack React'in blog gönderisini referans olarak kullanıyorum. Google_map.js satır 83'te hatanın nereye atıldığını izledim:

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

İşte şimdiye kadarki harita bileşenim. Son üç satır olan 58-60. Satırları yorumladığımda sayfa gayet iyi (harita olmadan) yükleniyor. düzenleme: @Dmitriy Nevzorov'un önerdiği değişiklikleri yaptım ve hala aynı hatayı veriyor.

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)

Ve işte bu harita bileşeninin main.js'de yönlendirildiği yer:

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
İki sahip export defaults ve olurdu new GoogleAPIComponent()değil GoogleAPIComponent()?
gcampbell

Varsayılanlardan birini kaldırdım ve önerinizi denedim. Görünüşe göre şu anda Google Haritalar ile konuşuyor, bu iyi, ancak sayfa yüklenmeden önce başka bir şifreleme hatası veriyor: Locations.js: 58 Yakalanmamış TypeError: (ara değer) bir işlev değil ". Herhangi bir fikir?
Mike Fleming

1
Ya kaldırırsanız (LocationContainer)?
gcampbell

Teşekkürler, sanırım anladım! Tuhaf, blog yazılarına böyle yazmışlar. Hala Google Haritalar'dan birkaç başka hata alıyorum, bunları buraya koyacağım: 'GoogleMap: apiKey kullanımdan kaldırıldı, bunun yerine bootstrapURLKeys = {{key: YOUR_API_KEY}} kullanın. google_map.js: 689 GoogleMap: center veya defaultCenterproperty tanımlanmalıdır google_map.js: 699 GoogleMap: zoom veya defaultZoom özelliği tanımlanmalıdır google_map.js: 704 '
Mike Fleming

1
Diğer hatalardan emin değilim, ancak ilkini düzeltmek için bunu deneyebilirsiniz:export default new GoogleApiComponent({ bootstrapURLKeys: MY_API_KEY })
gcampbell

Yanıtlar:


207

Benim extends React.Componentiçin sonunda yazmayı unuttuğumda oldu . Tam olarak sahip olduğun şey olmadığını biliyorum, ama umarım bu cevabı okuyan diğerleri bundan yararlanabilir.


19

1
Gönderinin özeti: Tarayıcıda bir sınıf ve bir işlevi ayırt etmek aslında tamamen önemsiz değildir ... "Asıl çözüm gerçekten basit, ancak React'in neden bu çözümle sonuçlandığını açıklamak için büyük bir teğet [yapacağım]. .. "blah, blah, blah, ... ->" React.Component'i genişletmezseniz, React prototip üzerinde isReactComponent'ı bulamaz ve bileşeni bir sınıf olarak ele almaz. "
spinkus

Harika. Benzer bir sorunla karşı karşıyaydım ve çözümünüz sorunu çözdü. Ama sözdizimim öyleydi import React, { Component } from 'react'; class extends Component. Ben değiştirerek bu sorunu çözmek sorunu nasıl yaptığını anlayamadık Componentile React.Component. İthalat önemli mi?
Arun Ramachandran

71

Benim için bunun nedeni, newAnimasyonlu durumu ayarlarken anahtar kelimeyi kullanmayı unutmuş olmamdı.

Örneğin:

fadeAnim: Animated.Value(0),

için

fadeAnim: new Animated.Value(0),

düzeltecekti.


1
Bu benim sorunumu çözdü, animasyonlu değil farklı bir kullanım durumu kullanıyordum ama yeni anahtar kelimeyi kullandıktan sonra çözdüm. Teşekkürler
Olivier JM

4
Olanları öğrenmeye çalışmak için 4 saat 44 dakika 4 saniye harcadı. Sen tanrısın.
Satheeshwaran

Evet, o da bendim. Teşekkür ederim!
James Cushing

64

tl; Dr.

React Router v4 <Route/>kullanıyorsanız, componentsınıf tabanlı React bileşeninizi geçmek için gerçekten pervane kullanıyorsanız bileşeninizi kontrol edin !

Daha genel olarak: Sınıfınız iyi görünüyorsa, onu çağıran kodun onu bir işlev olarak kullanmaya çalışıp çalışmadığını kontrol edin.

açıklama

Bu hatayı aldım çünkü React Router v4 kullanıyordum ve bir sınıf olan bileşenimi geçmek için yanlışlıkla bileşendeki renderyerine pervane kullandım . Bu bir sorundu, çünkü React bileşenleri üzerinde çalışacak olan bir işlev beklerken (çağırır) .component<Route/>rendercomponent

Yani bu kodda:

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

<Route/>Bileşeni içeren satır şu şekilde yazılmalıdır:

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

Bunu kontrol etmemeleri ve bu kadar kolay yakalanması kolay bir hata vermeleri utanç verici.


47

Bana oldu çünkü kullandım

PropTypes.arrayOf(SomeClass)

onun yerine

PropTypes.arrayOf(PropTypes.instanceOf(SomeClass))


Teşekkürler, benim durumumdaki sorun yanlış PropTypes tanımıydı.
Vasiliy

bu benim sorunumu çözdü! oldu PropTypes.oneOfType([SomeClass, SomeOtherClass]).isRequired,yerine PropTypes.oneOfType([PropTypes.instanceOf(SomeClass), PropTypes.instanceOf(SomeOtherClass)]).isRequired,
Doug

Teşekkürler, gerçekten uzun zamandır orada neyin yanlış gittiğini merak ediyordum!
Got The Fever Media

14

Yinelenen export defaultbeyanınız var. İlki, aslında bir fonksiyon olan ikincisi tarafından geçersiz kılınır.


İyi yakalama! Varsayılanı GoogleApiComponent'in önünde bıraktım ve hala aynı hatayı alıyorum. Alternatif olarak, tüm varsayılanları kaldırmak GoogleApiComponent üzerindeki terminalimde bana "beklenmeyen simge" hatası veriyor.
Mike Fleming

14

Benim için ComponentName.prototypebunun yerine oldu ComponentName.propTypes. PhpstormIDE tarafından otomatik önerildi . Umarım birine yardımcı olur.


14

Aynı sorunu yaşadım, ES6bileşen sınıfım genişlemediği için oluştu React.Component.


8

Çoğunlukla bu sorunlar, Bileşeni genişletmeyi tepki vermekten kaçırdığınızda ortaya çıkar :

import React, {Component} from 'react'

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

7

Benim için bunun nedeni propTypes yerine prototip kullanmamdı

class MyComponent extends Component {

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

MyComponent.prototype = {

};

olmalı

MyComponent.propTypes = {

};

Benim için tamamen aynı durum. Teşekkür ederim!
Tekson

6
Post.proptypes = {

}

için

Post.propTypes = {

}

böyle bir hatanın nasıl izleneceği konusunda çok kesin bir şekilde yorum yapılmalıdır.


1
Çözümünüzü / cevabınızı bazı detaylı bilgilerle açıklamak daha iyidir.
Dharmang

Yaah olur Bravo!
Mbanda

3

Görünüşe göre bu hata göründüğünde tek bir durum yok.

Yapıcıyı statefull bileşeninde bildirmediğimde başıma geldi.

class MyComponent extends Component {

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

onun yerine

class MyComponent extends Component {

    constructor(props) {
        super(props);
    }

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

3

Kontrol edebileceğiniz iki şey şudur:

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

Slider.propTypes = {
    // accessibility: PropTypes.bool,
}
  • React.Component'i genişlettiğinizden emin olun.
  • Kullanım propTypes yerine prototip (IDE intellisense göre)

Slider.propTypes olmalıdır: {}
David Casanellas

2

Bu genel bir sorundur ve tek bir durumda görünmez. Ancak, tüm durumlarda ortak sorun, importbelirli bir bileşeni unutmanızdır (kurduğunuz bir kitaplıktan veya oluşturduğunuz özel yapılmış bir bileşenden olması fark etmez):

import {SomeClass} from 'some-library'

Daha sonra içe aktarmadan kullandığınızda, derleyici bunun bir işlev olduğunu düşünür. Bu nedenle kırılır. Bu yaygın bir örnektir:

imports

...code...

ve sonra kodunuzun içinde bir yerde

<Image {..some props} />

Bileşeni içe aktarmayı unutursanız <Image />, derleyici diğer içe aktarmalarda olduğu gibi şikayet etmez, ancak kodunuza ulaştığında bozulur.


1

Benim için, renderyöntemimi yanlışlıkla sildim !

componentWillReceivePropsKısa bir renderyöntemin hemen önünde, artık ihtiyacım olmayan bir yönteme sahip bir sınıfım vardı . Acelemle onu kaldırırken, yanlışlıkla tüm renderyöntemi de kaldırdım .

Tamamen alakasız dosyalardaki yorumları sorunun "kaynağı" olarak gösteren konsol hataları alıyordum, bu takip edilmesi gereken bir ACI idi.


1

Render yöntemini yanlış çağırdığım benzer bir problem yaşadım

Bir hata verdi:

render = () => {
    ...
}

onun yerine

doğru:

render(){
    ...
}

1

Bunu yaptığımda da vardı:

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

doğru şekilde:

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

veya

const foo = ...
export default foo

1

Benim için bu, bağlantı işlevimi düzgün bir şekilde sarmadığım ve varsayılan iki bileşeni dışa aktarmaya çalıştığım için oldu


1

Yanlış sınıfı içe aktardığımda ve react-native içinde mobx kullanırken yanlış mağazaya başvurduğumda bu hatayla karşılaştım .

Bu pasajda hatayla karşılaştım:

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

@inject ("counter")
@Observer

Aşağıdaki gibi birkaç düzeltmeden sonra. Sorunumu bu şekilde çözdüm.

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

@inject("counterStore")
@observer

Ne yerine yanlış sınıfını kullanıyordum, aslında yanlış olduğunu observerkullandığım Observerve yerine counterStorekullandığım counter. Sorunumu bu şekilde çözdüm.


1

Dosyada MyComponent.js

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

Bu bileşenle ilgili bazı işlevler koydum:

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

export myFunction() {
...
}

ve sonra başka bir dosyada bu işlevi içe aktarın:

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

Sorunu görebiliyor musun?

Küme parantezlerini unuttum ve MyComponentadıyla ithal ettimmyFunction !

Yani, düzeltme şuydu:

import {myFunction} from './MyComponent'

1

Bunu, bir sınıf yerine bir işlevi içe aktarırken yanlış bir import ifadesi yazarken yaşadım. EğerremoveMaterial başka bir modülde bir fonksiyonudur:

Sağ:

import { removeMaterial } from './ClaimForm';

Yanlış:

import removeMaterial from './ClaimForm';

1

Bu hatayı küçük bir hata yaparak aldım. Benim hatam, sınıfı sınıf yerine işlev olarak dışa aktarmaktı. Sınıf dosyamın altında şunlar vardı:

export default InputField();

ne zaman olmalıydı:

export default InputField;

0

Ben de bununla karşılaştım, react bileşeninizin içinde bir javascript hatası olabilir. Bir bağımlılık kullanıyorsanız new, yeni örneği başlatmak için sınıfın işlecini kullandığınızdan emin olun . Hata atacaksa

this.classInstance = Class({})

bunun yerine kullan

this.classInstance = new Class({})

tarayıcıdaki hata zincirinde göreceksiniz

at ReactCompositeComponentWrapper._constructComponentWithoutOwner

bu inandığım eşantiyon.


0

HMR'yi durdurmayı deneyin ve npm startprojenizi yeniden inşa etmek için tekrar vurun .
Bu, hatayı yok etti, nedenini bilmiyorum.


0

Benim durumumda yazdığım commentyerin içinde Componentyanlışlıkla

Bunu şimdi yazdım.

import React, { Component } from 'react';

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

Bunun yerine.

import React, { Component } from 'react';

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

önemli değil ama benim gibi yeni başlayan biri için gerçekten kafa karıştırıcı. Umarım bu yardımcı olur.


0

Benim durumumda, JSX kullanıldığında bir üst bileşen "<>" olmadan diğer bileşenleri çağırıyordu

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

düzeltme

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

0

Buradaki başka bir rapor: Dışa aktardığım gibi çalışmadı:

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

onun yerine

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

Parantezlerin konumuna dikkat edin. Her ikisi de doğrudur ve bir linter veya daha güzel veya benzeri bir şey tarafından yakalanmayacaktır. Bulmam biraz zaman aldı.


0

Benim durumumda, sonunda olması gerekirken yanlışlıkla bileşen adı ( Home) connectişlevini ilk argüman olarak koydum . duh.

Bu kesinlikle bana hatayı verdi:

export default connect(Home)(mapStateToProps, mapDispatchToProps)

Ama bu kesinlikle işe yaradı:

export default connect(mapStateToProps, mapDispatchToProps)(Home)

0

Bu, yanlışlıkla renderişlevimi yanlış adlandırdığımda meydana geldi :

import React from 'react';

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

Bu hatanın örneğime, sınıfımın uygun bir renderyöntemi olmaması neden oldu .


0

Aslında tüm sorun yeniden bağlanıyor. çözümleri:

Doğru :

export default connect(mapStateToProps, mapDispatchToProps)(PageName)

Yanlış & Hata :

export default connect(PageName)(mapStateToProps, mapDispatchToProps)

-1

Benim için rootReducer.js'de bir redüktörün yanlış içe aktarılmasıydı. Redüktör dosyası yerine konteyner ithal ettim.

Misal

import settings from './pages/Settings';

Ama elbette olmalı

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

Ayarlar dizini aşağıdaki dosyaları içerir: actions.js, index.js, redüktör.js.

Bunu kontrol etmek için redux / es / redux.js'den assertReducerShape () işlevinin redüktör argümanlarını günlüğe kaydedebilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.