Uncaught Ошибка: Инвариантное Нарушение: Тип элемента недопустим: ожидал строку (для встроенных компонентов) или класса / функции, но получил: объект

529

Я получаю эту ошибку:

Uncaught Ошибка: Инвариантное Нарушение: Тип элемента недопустим: ожидал строку (для встроенных компонентов) или класс / функцию (для составных компонентов), но получил: объект.

Это мой код:

var React = require('react')
var ReactDOM =  require('react-dom')
var Router = require('react-router')
var Route = Router.Route
var Link = Router.Link

var App = React.createClass({
  render() {
    return (
      <div>
        <h1>App</h1>
        <ul>
          <li><Link to="/about">About</Link></li>
        </ul>
      </div>
    )
  }
})

var About = require('./components/Home')
ReactDOM.render((
  <Router>
    <Route path="/" component={App}>
      <Route path="about" component={About} />
    </Route>
  </Router>
), document.body)

Мой Home.jsxфайл:

var React = require('react');
var RaisedButton = require('material-ui/lib/raised-button');

var Home = React.createClass({
  render:function() {
    return (
        <RaisedButton label="Default" />
    );
  },
});

module.exports = Home;
Панкадж Тхакур
источник
7
Пожалуйста, посмотрите на stackoverflow.com/questions/36795819/…
Марсело Салазар
Эта ошибка может возникнуть, если вы попытаетесь импортировать несуществующий компонент . Убедитесь, что у вас нет опечатки и что компонент действительно назван так. В случае библиотек убедитесь, что вы используете правильную версию, так как компоненты могут иметь разные имена в разных версиях.
Тотимедли
Это также может произойти, когда вы определяете свойство, возможно, путем уничтожения ES6, с тем же именем, что и уже импортированный компонент (и пытаетесь передать его другому компоненту).
Филипп Мерфи

Ответы:

887

В моем случае ( с использованием Webpack ) это была разница между:

import {MyComponent} from '../components/xyz.js';

против

import MyComponent from '../components/xyz.js';

Второй работает, в то время как первый вызывает ошибку. Или наоборот.

JohnL
источник
81
Гуглер из будущего здесь, спасибо, это была моя проблема! Это имеет смысл в ретроспективе, так как первое - это деструктуризация экспорта, но если вы использовали default, то оно просто пытается деструктурировать функцию / класс.
ebolyen
3
Для будущих людей мой случай был опечаткой в ​​названии элемента, которое я использовал. Я изменился <TabBarIOS.item>на<TabBarIOS.Item>
Райан-Нил Мес
6
Огромный. Почему это так?
LOL
45
Для тех, кто все еще интересуется, почему это работает - {MyComponent} импортирует экспорт «MyComponent» из файла «../components/xyz.js» - второй импортирует экспорт по умолчанию из «../components/xyz.js».
ShaunYearStrong
Это также может быть связано с импортом внутри MyComponent. в моем случае ошибка упоминала MyComponent, но фактически оператор import внутри него вызывает ошибку: import {SomeLibraryCompenent} из 'some-library'
ykorach
159

вам нужно экспортировать по умолчанию или требовать (путь) .default

var About = require('./components/Home').default
jackypan1989
источник
2
У меня была эта проблема с 'response-native-navbar'. Я назвал default по требованию, и это исправило мою проблему. Спасибо.
Варан Пезешкян
3
Хм, добавление .default в моем случае решает проблему. Тем не менее, я на самом деле экспортирую Default Home расширяет Component для этого класса, поэтому я ожидал, что он будет работать без '.default'
Marc
3
Можете ли вы объяснить причину, например, что происходит, когда мы добавляем default?
Субхам Трипати
1
это сработало, но может кто-нибудь объяснить, что делает .default.
Бурак Карасой
1
@BurakKarasoy Вам нужен .default, поскольку стандартный способ сборки модулей Babel - преобразование export defaultоператоров, exports.defaultпоэтому вы должны использовать их .defaultпри импорте модуля. Один из способов избавиться от этого - использовать babel-plugin-add-module-exports, который восстанавливает поведение по умолчанию.
Жан-Батист Луазель
54

Вы только что модулировали какой-либо из ваших компонентов React? Если да, вы получите эту ошибку, если вы забыли указать module.exports , например:

немодулированный ранее действующий компонент / код:

var YourReactComponent = React.createClass({
    render: function() { ...

модульный компонент / код с помощью module.exports :

module.exports = React.createClass({
    render: function() { ...
Charlez
источник
2
Будет ли то же самое создать класс и затем экспортировать? Как ваш первый фрагмент, а затемmodule.exports = YourReactComponent
Ник Пинеда
3
Я смог упростить это до:export default class YourReactComponent extends React.Component {
cpres
Получаю ту же ошибку. Я могу сделать это в одном компоненте, но не могу сделать в другом.
Mr_Perfect
Даже я упоминал, что module.exportsвсе еще получаю ошибку
Mr_Perfect
20

Если вы получаете эту ошибку, это может быть потому, что вы импортируете ссылку, используя

import { Link } from 'react-router'

вместо этого может быть лучше использовать

import {Link} из'act-router-dom '
                      ^ -------------- ^

Я считаю, что это требование для версии 4 реактивного маршрутизатора

NSCoder
источник
Мой друг импортировал ссылку из react, а не react-router-dom. Исправлена ​​проблема. Никогда не видел это сообщение об ошибке раньше.
О-9
18

https://github.com/rackt/react-router/blob/e7c6f3d848e55dda11595447928e843d39bed0eb/examples/query-params/app.js#L4 Router также является одним из свойств react-router. Так что для изменения ваших модулей требуется такой код:

  var reactRouter = require('react-router')
  var Router = reactRouter.Router
  var Route = reactRouter.Route
  var Link = reactRouter.Link

Если вы хотите использовать синтаксис ES6, используйте link ( import), используйте babel в качестве помощника.

Кстати, чтобы сделать ваш код работает, мы можем добавить {this.props.children}в App, как

render() {
  return (
    <div>
      <h1>App</h1>
      <ul>
        <li><Link to="/about">About</Link></li>
      </ul>
      {this.props.children}
    </div>

  )
}
Дэвид Гуан
источник
Извините за то, что не проверили внимательно прошлой ночью, в вашем домашнем компоненте нет проблем. Можете ли вы попробовать то, что я только что отредактировал?
Дэвид Гуан
18

Не удивляйтесь списку ответов на один вопрос. Есть различные причины для этой проблемы;

Для моего случая предупреждение было

warning.js: 33 Предупреждение: React.createElement: тип недопустим - ожидается строка (для встроенных компонентов) или класс / функция (для составных компонентов), но получено: undefined. Вы, вероятно, забыли экспортировать свой компонент из файла, в котором он определен. Проверьте код по адресу index.js: 13.

Сопровождается ошибкой

invariant.js: 42 Uncaught Ошибка: недопустимый тип элемента: ожидается строка (для встроенных компонентов) или класс / функция (для составных компонентов), но получено: undefined. Вы, вероятно, забыли экспортировать свой компонент из файла, в котором он определен.

Я не мог понять ошибку, так как она не упоминает ни один метод или имя файла. Я смог решить только после просмотра этого предупреждения, упомянутого выше.

У меня есть следующая строка в index.js.

<ConnectedRouter history={history}>

Когда я погуглил вышеупомянутую ошибку с ключевым словом «ConnectedRouter», я нашел решение на странице GitHub.

Ошибка в том, что когда мы устанавливаем react-router-reduxпакет, по умолчанию мы устанавливаем этот. https://github.com/reactjs/react-router-redux, но не фактическая библиотека.

Чтобы устранить эту ошибку, установите соответствующий пакет, указав область действия npm с помощью @

npm install react-router-redux@next

Вам не нужно удалять неправильно установленный пакет. Он будет автоматически перезаписан.

Спасибо.

PS: даже предупреждение помогает вам. Не пренебрегайте предупреждением, просто глядя на ошибку в одиночку.

Баласубрамани М
источник
Я хотел бы проголосовать за это несколько раз.
Cizaphil
15

В моем случае один из экспортированных дочерних модулей не возвращал должный компонент реакции.

const Component = <div> Content </div>;

вместо

const Component = () => <div>Content</div>;

Показанная ошибка была для родителя, следовательно, не мог выяснить.

Катти
источник
11

В моем случае это было вызвано неправильными символами комментариев. Это не верно:

<Tag>
    /*{ oldComponent }*/
    { newComponent }
</Tag>

Это правильно:

<Tag>
    {/*{ oldComponent }*/}
    { newComponent }
</Tag>

Обратите внимание на фигурные скобки

tuanh118
источник
10

У меня такая же ошибка: ОШИБКА ИСПРАВЛЕНИЯ !!!!

Я использую 'response-router-redux' v4, но она плохая .. После npm установите response-router-redux @ next, я нахожусь на "Reaction-router-redux": "^ 5.0.0-alpha.9",

И ЭТО РАБОТАЕТ

Thibault Jp
источник
8

Я получил это, import App from './app/';ожидая, что он будет импортирован ./app/index.js, но вместо этого он импортирован ./app.json.

tybro0103
источник
2
И это объяснение: github.com/facebook/react-native/issues/12539
sfratini
8

У меня возникла та же проблема, и я понял, что предоставляю компонент Undefined React в разметке JSX. Дело в том, что компонент рендеринга для рендеринга был рассчитан динамически, и он оказался неопределенным!

Ошибка указана:

Нарушение инварианта: недопустимый тип элемента: ожидается строка (для встроенных компонентов) или класс / функция (для составных компонентов), но получено: undefined. Вы, вероятно, забыли экспортировать свой компонент из файла, в котором он определен. Проверьте метод визуализации C.,

Пример, выдающий эту ошибку:

var componentA = require('./components/A');
var componentB = require('./components/B');

const templates = {
  a_type: componentA,
  b_type: componentB
}

class C extends React.Component {
  constructor(props) {
    super(props);
  }
  
  // ...
  
  render() {
    //Let´s say that depending on the uiType coming in a data field you end up rendering a component A or B (as part of C)
    const ComponentTemplate = templates[this.props.data.uiType];
    return <ComponentTemplate></ComponentTemplate>
  }
  
  // ...
}

Проблема состояла в том, что был предоставлен недопустимый «uiType», и поэтому это приводило к неопределенному результату:

templates['InvalidString']

CSN
источник
Кажется, у меня есть похожая ошибка с response-fine-uploader, но я ничего не могу понять (пока). У него есть компонент Gallery, который я импортирую, и он тоже идет к своему методу рендеринга, но в этом возникает ошибка рендеринга, я не уверен, является ли это проблемой библиотеки или моей проблемой, так как я совершенно новый, чтобы реагировать.
Зия Уль Рехман
Была похожая ошибка, где была ошибка в сложном компоненте. Простой метод отладки - временно упростить компонент, например, const MyComponent = () => <div>my component</div>;просто посмотреть, нормально ли тогда работает импорт.
metakermit
Было бы удобно иметь возможность обнаружить это, например, с помощью правила lint.
Уилл Каин
7

Просто как быстрое дополнение к этому. У меня была та же проблема, и пока Webpack компилировал мои тесты, и приложение работало нормально. Когда я импортировал свой компонент в тестовый файл, я использовал неправильный регистр в одном из импортов, и это вызывало ту же ошибку.

import myComponent from '../../src/components/myComponent'

Должны были быть

import myComponent from '../../src/components/MyComponent'

Обратите внимание, что имя импорта myComponentзависит от имени экспорта внутри MyComponentфайла.

Blackout1985
источник
7

Подобные проблемы возникали с последними версиями React Native 0.50 и выше.

Для меня это была разница между:

import App from './app'

а также

import App from './app/index.js'

(последний исправил проблему). Мне понадобились часы, чтобы уловить этот странный, трудно заметный нюанс :(

Олег Датер
источник
6

Другое возможное решение, которое сработало для меня:

В настоящее время react-router-reduxнаходится в бета-версии и npm возвращает 4.x, но не 5.x. Но @types/react-router-reduxвернул 5.х. Так что были использованы неопределенные переменные.

Заставить NPM / Yarn использовать 5.x решил это за меня.

Флориан Рихтер
источник
6

Учитывая вашу ошибку:

'Uncaught Error: Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function but got: object'

У вас есть 2 варианта:

  1. Ваш файл экспорта может иметь слово defaultкак в. export default class ____.... Тогда ваш импорт должен будет избегать использования {}вокруг него. Как вimport ____ from ____

  2. Избегайте использования слова по умолчанию. Тогда ваш экспорт выглядит как export class ____... Тогда ваш импорт должен использовать {}. подобноimport {____} from ____

jasonleonhard
источник
Отличный ответ !!! +1 ... Я полностью упустил из виду export default {component name}и забыл добавить его
Si8
@ Si8 Рад быть полезным и спасибо, что заставил меня улыбнуться первым делом с утра.
Джейсон Леонард
5

В моем случае импорт происходил неявно из-за библиотеки.

Мне удалось это исправить, изменив

export class Foo

в

export default class Foo,

thedayturns
источник
5

Я столкнулся с этой ошибкой, когда у меня были файлы .jsx и .scss в одном каталоге с тем же корневым именем.

Так, например, если у вас есть Component.jsxи Component.scssв одной папке, и вы пытаетесь сделать это:

import Component from ./Component

Webpack явно запутался и, по крайней мере, в моем случае, пытается импортировать файл scss, когда мне действительно нужен файл .jsx.

Я смог это исправить, переименовав файл .scss и избежав двусмысленности. Я мог бы также явно импортировать Component.jsx

bergie3000
источник
1
Вы, сэр, спасатель жизни. В моем случае это был, по сути, Component.json (файл данных).
Tengen
4

И в моем случае я просто пропустил точку с запятой при импортировании-декларации в одном из моих субмодулей.

Исправлено, изменив это:

import Splash from './Splash'

к этому:

import Splash from './Splash';
Рикард Аскелёф
источник
2
О, мой бог. Чувак, ты спас мне жизнь. Я действительно не понимаю, почему строитель не сообщает об этом тебе.
Милан Влах
4

В моем случае я использовал экспорт по умолчанию, но не экспортировал functionили React.Component, а просто JSXэлемент, т.е.

Ошибка:

export default (<div>Hello World!</div>)

Работает :

export default () => (<div>Hello World!</div>)
Andru
источник
2

В дополнение к import/ exportпроблем, упомянутых. Я нашел использовать, React.cloneElement()чтобы добавитьprops к дочернему элементу, а затем его рендеринг дал мне ту же ошибку.

Я должен был изменить:

render() {
  const ChildWithProps = React.cloneElement(
    this.props.children,
    { className: `${PREFIX}-anchor` }
  );

  return (
    <div>
      <ChildWithProps />
      ...
    </div>
  );
}

чтобы:

render() {
  ...
  return (
    <div>
      <ChildWithProps.type {...ChildWithProps.props} />
    </div>
  );
}

Смотрите React.cloneElement() документы для получения дополнительной информации.

Грег К
источник
2

Я получил эту ошибку в реакции маршрутизации, проблема была в том, что я использовал

<Route path="/" component={<Home/>} exact />

но это был неправильный маршрут требует компонента в качестве класса / функции, поэтому я изменил его на

<Route path="/" component={Home} exact />

и это сработало. (Просто избегайте скобок вокруг компонента)

НАКСА КОНСАЛТИНГ
источник
По-другому, мое решение было обратным :), но я благодарю вас, чтобы открыть мои глаза.
Юлио Алеман Хименес
1

Для меня это было то, что мои стилевые компоненты были определены после определения моего функционального компонента. Это происходило только в постановке, а не локально для меня. Как только я переместил свои styled-компоненты выше определения компонентов, ошибка исчезла.

Jadam
источник
1

Это означает, что некоторые из ваших импортированных Компонентов ошибочно объявлены или не существуют

У меня была похожая проблема, я сделал

import { Image } from './Shared'

но когда я посмотрел в общий файл, у меня не было компонента «изображение», а компонент «ItemImage»

import { ItemImage } from './Shared';

Это происходит, когда вы копируете код из других проектов;)

веб-мастер
источник
1

У меня была проблема React.Fragment, потому что версия моей реакции была < 16.2, поэтому я от нее избавился.

Евгений Ихнацю
источник
0

@Balasubramani M спас меня здесь. Хотел добавить еще одного, чтобы помочь людям. Это проблема, когда вы склеиваете слишком много вещей и не разбираетесь в версиях. Я обновил версию материала-UI и нужно изменить

import Card, {CardContent, CardMedia, CardActions } from "@material-ui/core/Card"; 

к этому:

import Card from '@material-ui/core/Card';
import CardActions from '@material-ui/core/CardActions';
import CardContent from '@material-ui/core/CardContent';
import CardMedia from '@material-ui/core/CardMedia';
Кайл Пеннелл
источник
0

У меня была та же проблема, и проблема была в том, что некоторые js-файлы не были включены в пакет этой конкретной страницы. Попробуйте включить эти файлы, и проблема может быть решена. Я сделал это:

.Include("~/js/" + jsFolder + "/yourjsfile")

и это исправило проблему для меня.

Это было в то время как я использовал React в Dot NEt MVC

Джейсон
источник
0

Я обнаружил другую причину этой ошибки. Это связано с тем, что CSS-in-JS возвращает нулевое значение JSX верхнего уровня функции возврата в компоненте React.

Например:

const Css = styled.div`
<whatever css>
`;
export function exampleFunction(args1) {
  ...
  return null;
}

export default class ExampleComponent extends Component {
...
render() {
const CssInJs = exampleFunction(args1);
  ...
  return (
    <CssInJs>
      <OtherCssInJs />
      ...
    </CssInJs>
  );
}

Я бы получил это предупреждение:

Предупреждение: React.createElement: тип недопустим - ожидается строка (для встроенных компонентов) или класс / функция (для составных компонентов), но получено: null.

После этой ошибки:

Uncaught Error: недопустимый тип элемента: ожидается строка (для встроенных компонентов) или класс / функция (для составных компонентов), но получено: null.

Я обнаружил, что это потому, что не было CSS с компонентом CSS-in-JS, который я пытался визуализировать. Я исправил это, убедившись, что возвращается CSS, а не нулевое значение.

Например:

const Css = styled.div`
<whatever css>
`;
export function exampleFunction(args1) {
  ...
  return Css;
}

export default class ExampleComponent extends Component {
...
render() {
const CssInJs = exampleFunction(args1);
  ...
  return (
    <CssInJs>
      <OtherCssInJs />
      ...
    </CssInJs>
  );
}
codeinaire
источник
0

Я получаю почти ту же ошибку:

Uncaught (в обещании) Ошибка: недопустимый тип элемента: ожидается строка (для встроенных компонентов) или класс / функция (для составных компонентов), но есть: объект.

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

импортировать FooBarList из 'team-ui';

в

импортировать FooBarList из 'team-ui / lib / components / foo-bar-list / FooBarList';

Патрик
источник
0

В моем случае это был внешний компонент, импортированный так:

import React, { Component } from 'react';

а затем объявлено как:

export default class MyOuterComponent extends Component {

где внутренний компонент импортировал пустой React:

import React from 'react';

и расставил точки для объявления:

export default class MyInnerComponent extends ReactComponent {

krayzk
источник
0

В моем случае мне потребовалось много времени, чтобы найти и проверить возможные пути, но это было исправлено только так: удалите "{", "}" при импорте пользовательского компонента:

import OrderDetail from './orderDetail';

Мой неправильный путь был:

import { OrderDetail } from './orderDetail';

Потому что в файле orderDetail.js я экспортировал OrderDetail в качестве класса по умолчанию:

class OrderDetail extends Component {
  render() {
    return (
      <View>
        <Text>Here is an sample of Order Detail view</Text>
      </View>
    );
  }
}

export default OrderDetail;
tiennsloit
источник