Отримання "Неможливо викликати клас як функцію" в моєму React Project


130

Я намагаюся додати компонент карти React до свого проекту, але зіткнувся з помилкою. Я використовую повідомлення в блозі Fullstack React як довідник. Я простежив, куди помилка потрапляє в рядок 83 google_map.js:

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'))

2
У вас є два export defaultс, і це було б new GoogleAPIComponent()НЕ GoogleAPIComponent()?
gcampbell

Я прибрав один із значень за замовчуванням і спробував вашу пропозицію. Схоже, зараз він фактично спілкується з Google Maps, що добре, але перед завантаженням сторінки вона видає ще одну криптовану помилку: Locations.js: 58 Uncaught TypeError: (проміжне значення) - це не функція ". Будь-які ідеї?
Майк Флемінг

1
Що робити, якщо ви видалите (LocationContainer)?
gcampbell

Дякую, я думаю, що це дісталося! Дивно, саме так вони написали у своєму дописі на блозі. Отримавши декілька інших помилок з Карт Google, я викладу їх тут: 'GoogleMap: apiKey застаріло, замість цього використовуйте bootstrapURLKeys = {{key: YOUR_API_KEY}}. google_map.js: 689 GoogleMap: центр або за замовчуваннямCenterproperty має бути визначено google_map.js: 699 GoogleMap: масштабування або за замовчуваннямЗавласності має бути визначено google_map.js: 704 '
Майк Флемінг

1
Я не впевнений в інших помилках, але ви можете спробувати це виправити першою:export default new GoogleApiComponent({ bootstrapURLKeys: MY_API_KEY })
gcampbell

Відповіді:


207

Для мене це сталося, коли я забув писати extends React.Componentнаприкінці. Я знаю, що це не саме те, що ти мав, але інші, хто читає цю відповідь, можуть отримати користь від цього, сподіваємось.


19
Є чудовий пост на переоцінене, що пояснює, чому це працює
завищеною

1
Короткий зміст повідомлення: Розмежування класу та функції у браузері насправді не зовсім тривіальне ... "Дійсне рішення насправді просте, але [я продовжую] величезну дотичну пояснення, чому React закінчився цим рішенням. .. "bla, blah, blah, ... ->" Якщо ви не розширите React.Component, React не знайде isReactComponent в прототипі і не буде розглядати компонент як клас. "
шпигун

Чудово. Я зіткнувся з подібною проблемою, і ваше рішення виправило проблему. Але мій синтаксис був import React, { Component } from 'react'; class extends Component. Я не міг зрозуміти, як це вирішило проблему, замінивши Componentна React.Component. Чи має значення імпорт?
Арун Рамачандран

70

Для мене це було тому, що я забув використовувати newключове слово під час налаштування анімованого стану.

наприклад:

fadeAnim: Animated.Value(0),

до

fadeAnim: new Animated.Value(0),

виправив би це.


1
Це вирішило мою проблему, я використовував інший випадок використання, не анімований, але після використання нового ключового слова вирішив його. Дякую
Олів'є JM

4
Провів 4 години 44 хвилини і 4 секунди, намагаючись дізнатися, що сталося. Ти бог.
Satheeshwaran

Так, це я теж був. Дякую!
Джеймс Кушинг

64

тл; д-р

Якщо ви використовуєте React Router v4, перевірте свій <Route/>компонент, чи дійсно ви використовуєте componentопору для передачі компонента React на основі класу!

Більш загально: Якщо ваш клас здається нормальним, перевірте, чи не викликає код, який викликає його, як функцію.

Пояснення

Я отримав цю помилку, тому що я використовував React Router v4, і я випадково використовував renderреквізит замість того, що componentзнаходиться в <Route/>компоненті, щоб передати мій компонент, який був класом. Це було проблемою, оскільки renderочікує (викликає) функцію, в той час componentяк та, яка буде працювати над компонентами React.

Отже, у цьому коді:

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

Рядок, що містить <Route/>компонент, повинен був бути записаний так:

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

Прикро, що вони не перевіряють це і дають корисну помилку для такої та легко зрозуміти помилку.


47

Сталося зі мною, бо я звик

PropTypes.arrayOf(SomeClass)

замість

PropTypes.arrayOf(PropTypes.instanceOf(SomeClass))


Дякую, помилка визначення PropTypes була проблемою в моєму випадку.
Василь

це вирішило моє питання! був PropTypes.oneOfType([SomeClass, SomeOtherClass]).isRequired,замість PropTypes.oneOfType([PropTypes.instanceOf(SomeClass), PropTypes.instanceOf(SomeOtherClass)]).isRequired,
Doug

Дякую, справді довго цікавився, що там не так!
Отримав лихоманку

14

Ви дублювали export defaultдекларацію. Перший переосмислюється другим, який фактично є функцією.


Гарний улов! Я залишив за замовчуванням перед GoogleApiComponent і все одно отримую ту ж помилку. Крім того, видалення всіх значень за замовчуванням дає мені помилку "несподіваного маркера" в моєму терміналі на GoogleApiComponent.
Майк Флемінг

14

Для мене це було ComponentName.prototypeзамість ComponentName.propTypes. автоматично запропоновано PhpstormIDE. Сподіваюся, це комусь допоможе.


14

У мене виникло те саме питання, це сталося тому, що мій ES6клас компонентів не розширювався React.Component.


8

В основному ці проблеми виникають, коли ви пропускаєте розширення компонента від реакції:

import React, {Component} from 'react'

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

7

Для мене це було тому, що я використовував прототип замість propTypes

class MyComponent extends Component {

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

MyComponent.prototype = {

};

це повинно бути

MyComponent.propTypes = {

};

Точний той самий випадок і для мене. Дякую!
Тексон

6
Post.proptypes = {

}

до

Post.propTypes = {

}

хтось повинен прокоментувати, як слідкувати за такою помилкою дуже точно.


1
Краще пояснити своє рішення / відповідь детальною інформацією.
Дхарманг

Яа, буває, Браво!
Мбанда

3

Схоже, немає жодного випадку, коли з’являється ця помилка.

Сталося зі мною, коли я не оголосив конструктор у стані.

class MyComponent extends Component {

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

замість

class MyComponent extends Component {

    constructor(props) {
        super(props);
    }

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

3

Ви можете перевірити дві речі:

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

Slider.propTypes = {
    // accessibility: PropTypes.bool,
}
  • Переконайтеся, що ви розширили React.Component
  • Використовуйте propTypes замість прототипу (відповідно до інтелігенції IDE)

має бути Slider.propTypes: {}
Девід Казанелласа

2

Це загальне питання і не з’являється в одному випадку. Але загальна проблема у всіх випадках полягає в тому, що ви забудете importконкретний компонент (неважливо, чи це з бібліотеки, яку ви встановили, або створеного на замовлення компонента):

import {SomeClass} from 'some-library'

Використовуючи його пізніше, не імпортуючи, компілятор вважає, що це функція. Тому він ламається. Це поширений приклад:

imports

...code...

а потім десь усередині вашого коду

<Image {..some props} />

Якщо ви забули імпортувати компонент, <Image />тоді компілятор не поскаржиться, як це стосується іншого імпорту, але зламається, коли він дійде до вашого коду.


1

Для мене це було тому, що я випадково видалив свій renderметод!

У мене був клас із componentWillReceivePropsметодом, який мені більше не потрібен, безпосередньо перед тим, як короткий renderметод. У поспіху видаливши його, я випадково видалив і весь renderметод.

Це було ПІДПРИЙМАННЯ , оскільки я отримував помилки консолі, вказуючи на коментарі в абсолютно невідповідних файлах як на "джерело" проблеми.


1

У мене була подібна проблема, я неправильно викликав метод візуалізації

Помилка:

render = () => {
    ...
}

замість

правильно:

render(){
    ...
}

1

У мене це було, коли я це робив:

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

правильно:

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

або

const foo = ...
export default foo

1

Для мене це сталося тому, що я не завершив функцію підключення належним чином і намагався експортувати два компоненти за замовчуванням


1

Я зіткнувся з цією помилкою, коли імпортував неправильний клас і перейшов до неправильного магазину під час використання mobx в реактивній.

У цьому фрагменті я зіткнувся з помилкою:

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

@inject ("counter")
@Observer

Після кількох виправлень, як, як показано нижче, фрагмент. Я вирішив своє питання так.

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

@inject("counterStore")
@observer

Що насправді було неправильним, я використовував неправильний клас замість того, що observerя використовував, Observerа не counterStoreвикористовував counter. Я вирішив своє питання так.


1

У файлі 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"
...

Чи можете ви помітити проблему?

Я забув фігурні брекети і імпортував MyComponentпід назвою myFunction!

Отже, виправлення було:

import {myFunction} from './MyComponent'

1

Я відчував це під час написання заяви про імпорт неправильно під час імпорту функції, а не класу. Якщо removeMaterialє функція в іншому модулі:

Право:

import { removeMaterial } from './ClaimForm';

Неправильно:

import removeMaterial from './ClaimForm';

1

Я отримав цю помилку, зробивши невелику помилку. Моя помилка - експорт класу як функції, а не як класу. Внизу файлу мого класу я мав:

export default InputField();

коли це мало бути:

export default InputField;

0

Я також зіткнувся з цим, можливо, у вас є помилка javascript всередині вашого компонента реакції. Переконайтесь, що ви використовуєте залежність, якою ви користуєтесь newоператором класу для інстанціювання нового екземпляра. Помилка викине, якщо

this.classInstance = Class({})

замість цього використовувати

this.classInstance = new Class({})

ви побачите у ланцюжку помилок у браузері

at ReactCompositeComponentWrapper._constructComponentWithoutOwner

в це я віддаюсь.


0

Спробуйте зупинити HMR і натисніть npm startзнову, щоб відновити проект.
Це зробило помилку зникнення, не знаю чому.


0

У моєму випадку я написав commentзамість Componentпомилки

Я щойно це написав.

import React, { Component } from 'react';

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

Замість цього.

import React, { Component } from 'react';

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

це не велика справа, але для початківця, як я, це справді заплутано. Я сподіваюся, що це буде корисним.


0

У моєму випадку, використовуючи JSX, батьківський компонент викликав інші компоненти без "<>"

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

виправити

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

0

Ще один звіт тут: це не спрацювало, коли я експортував:

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

замість

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

Зверніть увагу на положення дужок. Обидва є правильними, і їх не зачепить ні лінтер, ні гарніша, ні щось подібне. Зайняв мене час, щоб відстежити це.


0

У моєму випадку я випадково поставив ім'я компонента ( Home) як перший аргумент для connectфункціонування, тоді як він мав бути в кінці. дух.

Цей, безумовно, - припустив мені помилку:

export default connect(Home)(mapStateToProps, mapDispatchToProps)

Але цей працював - точно - добре:

export default connect(mapStateToProps, mapDispatchToProps)(Home)

0

Це сталося, коли я випадково renderнеправильно назвав свою функцію:

import React from 'react';

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

Мій приклад цієї помилки був викликаний просто тим, що в моєму класі не було належного renderметоду.


0

Насправді всі проблеми з редукційним підключенням. рішення:

Правильно :

export default connect(mapStateToProps, mapDispatchToProps)(PageName)

Неправильно та помилка :

export default connect(PageName)(mapStateToProps, mapDispatchToProps)

-1

Для мене це був неправильний імпорт редуктора в rootReducer.js. Я імпортував контейнер замість файлу редуктора.

Приклад

import settings from './pages/Settings';

Але впевнений, що так і має бути

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

Там, де каталог налаштувань містить такі файли Actions.js, index.js, reducer.js.

Щоб перевірити це, ви можете увімкнути аргументи редукторів функції assertReducerShape () від redux / es / redux.js.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.