Получение «Невозможно вызвать класс как функцию» в моем проекте React

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, последние три строки. edit: я внес изменения, которые предложил @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 Maps, я помещаю их здесь: 'GoogleMap: apiKey устарел, используйте вместо этого bootstrapURLKeys = {{key: YOUR_API_KEY}}. google_map.js: 689 GoogleMap: center или defaultCenterproperty должен быть определен google_map.js: 699 GoogleMap: zoom или defaultZoomproperty должен быть определен google_map.js: 704 '
Майк Флеминг
1
Я не уверен насчет других ошибок, но вы можете попробовать это исправить первую:export default new GoogleApiComponent({ bootstrapURLKeys: MY_API_KEY })
gcampbell

Ответы:

207

Для меня это случилось, когда я забыл написать extends React.Componentв конце. Я знаю, что это не совсем то, что у ВАС было, но, надеюсь, другие, читающие этот ответ, могут извлечь из этого пользу.

программист
источник
19
Там здорово пост в переусердствовал , что объясняет , почему это работает overreacted.io/how-does-react-tell-a-class-from-a-function
Эрик Kigathi
1
Краткое содержание сообщения: Различение между классом и функцией в браузере на самом деле не совсем тривиально ... «Фактическое решение действительно простое, но [я собираюсь] сделать важный шаг, чтобы объяснить, почему React остановился на этом решении. .. "бла, бла, бла, ... ->" Если вы не расширите React.Component, React не найдет isReactComponent в прототипе и не будет рассматривать компонент как класс. "
spinkus
Отлично. Я столкнулся с аналогичной проблемой, и ваше решение устранило проблему. Но мой синтаксис был import React, { Component } from 'react'; class extends Component. Я не мог понять, как это решило проблему, заменив Componentна React.Component. Имеет ли значение импорт?
Арун Рамачандран,
70

Для меня это было потому, что я забыл использовать newключевое слово при настройке состояния Animated.

например:

fadeAnim: Animated.Value(0),

в

fadeAnim: new Animated.Value(0),

исправлю это.

Уильям Парк
источник
1
Это решило мою проблему, я использовал другой вариант использования, а не анимацию, но после использования ключевого слова new решил его. Спасибо
Olivier JM
4
Потратил 4 часа 44 минуты и 4 секунды, пытаясь узнать, что произошло. Ты Бог.
Satheeshwaran 04
Ага, это тоже был я. Спасибо!
Джеймс Кушинг
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} />

Обидно, что они не проверяют это и выдают полезную ошибку за такую ​​легко обнаруживаемую ошибку.

totymedli
источник
47

Со мной случилось, потому что я использовал

PropTypes.arrayOf(SomeClass)

вместо того

PropTypes.arrayOf(PropTypes.instanceOf(SomeClass))

Дан Балабан
источник
Спасибо, неправильное определение PropTypes было проблемой в моем случае.
Василий
это решило мою проблему! был PropTypes.oneOfType([SomeClass, SomeOtherClass]).isRequired,вместо PropTypes.oneOfType([PropTypes.instanceOf(SomeClass), PropTypes.instanceOf(SomeOtherClass)]).isRequired,
Дуг
Спасибо, очень долго думал, что там не так!
Получил The Fever Media
14

Вы продублировали export defaultдекларацию. Первый заменяется вторым, который на самом деле является функцией.

Дмитрий Невзоров
источник
Хороший улов! Я оставил значение по умолчанию перед GoogleApiComponent, но все равно получаю ту же ошибку. Кроме того, удаление всех значений по умолчанию дает мне "неожиданную ошибку токена" в моем терминале в GoogleApiComponent.
Mike Fleming
14

Для меня это было ComponentName.prototypeвместо ComponentName.propTypes. авто предложено PhpstormIDE. Надеюсь, это кому-то поможет.

codersaif
источник
14

У меня возникла та же проблема, потому что мой ES6класс компонента не расширялся React.Component.

Варенье
источник
8

В основном эти проблемы возникают, когда вы пропускаете расширение Component из response:

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 = {

};
Оненгие Ричард
источник
Точно такой же случай для меня. Спасибо!
Tekson
6
Post.proptypes = {

}

в

Post.propTypes = {

}

кто-то должен прокомментировать, как очень точно отслеживать такую ​​ошибку.

Mbanda
источник
1
Лучше пояснить свое решение / ответ более подробной информацией.
Дхарманг
Да, такое бывает, Браво!
Mbanda
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 intellisense)
Дипен Дедания
источник
должно быть 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 в react-native.

Я столкнулся с ошибкой в ​​этом фрагменте:

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

@inject ("counter")
@Observer

После нескольких исправлений, как показано ниже. Так я решил свою проблему.

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

@inject("counterStore")
@observer

Что на самом деле было не так, я использовал неправильный класс вместо того, observerчто использовал, Observerи вместо того, чтобы counterStoreиспользовать counter. Так я решил свою проблему.

badarshahzad
источник
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';
shacker
источник
1

Я получил эту ошибку, сделав небольшую ошибку. Моя ошибка заключалась в экспорте класса как функции, а не как класса. Внизу моего файла класса у меня было:

export default InputField();

когда это должно было быть:

export default InputField;
airvine
источник
0

Я также столкнулся с этим, возможно, у вас есть ошибка javascript внутри вашего компонента реакции. Убедитесь, что при использовании зависимости вы используете newоператор класса для создания нового экземпляра. Ошибка выдает, если

this.classInstance = Class({})

вместо этого используйте

this.classInstance = new Class({})

вы увидите в цепочке ошибок в браузере

at ReactCompositeComponentWrapper._constructComponentWithoutOwner

я считаю, что это раздача.

Mibbit
источник
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();
     }
  }

это не имеет большого значения, но для новичка вроде меня это действительно сбивает с толку. Надеюсь, это будет полезно.

Uddesh_jain
источник
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)
scaryguy
источник
0

Это произошло, когда я случайно renderнеправильно назвал свою функцию:

import React from 'react';

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

Мой экземпляр этой ошибки был вызван просто тем, что у моего класса не было подходящего renderметода.

Брайан Бор
источник
0

Собственно все проблемы redux подключаются. решения:

Правильно :

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.

Чтобы проверить это, вы можете зарегистрировать аргументы redux для функции assertReducerShape () из файла redux / es / redux.js.

Олег Шишков
источник