Erreur non détectée: violation invariante: le type d'élément n'est pas valide: attend une chaîne (pour les composants intégrés) ou une classe / fonction mais a obtenu: objet

529

Je reçois cette erreur:

Erreur non détectée: violation invariante: le type d'élément n'est pas valide: attendait une chaîne (pour les composants intégrés) ou une classe / fonction (pour les composants composites) mais a obtenu: objet.

Voici mon code:

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)

Mon Home.jsxdossier:

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;
Pankaj Thakur
la source
7
Veuillez jeter un œil à stackoverflow.com/questions/36795819/…
Marcelo Salazar
Copie
Jim G.
Cette erreur peut augmenter si vous essayez d'importer un composant inexistant . Assurez-vous que vous n'avez pas de faute de frappe et que le composant porte bien ce nom. Dans le cas des bibliothèques, assurez-vous d'utiliser la bonne version, car les composants peuvent avoir des noms différents dans différentes versions.
totymedli
Cela peut également se produire lorsque vous définissez une propriété, peut-être par destruction ES6, avec le même nom qu'un composant déjà importé (et essayez de la transmettre à un autre composant).
Philip Murphy

Réponses:

887

Dans mon cas (en utilisant Webpack ), c'était la différence entre:

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

contre

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

Le second fonctionne alors que le premier est à l'origine de l'erreur. Ou le contraire.

JohnL
la source
81
Googleur du futur ici, merci, c'était mon problème! Cela a du sens rétrospectivement, car le premier est la déstructuration de l'exportation, mais si vous avez utilisé la valeur par défaut, il s'agit simplement de détruire une fonction / classe.
ebolyen
3
Pour les futures personnes, mon cas était une faute de frappe dans le nom de l'élément que j'utilisais. J'ai changé <TabBarIOS.item>pour<TabBarIOS.Item>
Ryan-Neal Mes
6
Énorme. pourquoi est-ce le cas?
lol
45
Pour tous ceux qui se demandent encore pourquoi cela fonctionne - {MyComponent} importe l'exportation 'MyComponent' du fichier '../components/xyz.js' - La seconde importe l' exportation par défaut de '../components/xyz.js'.
ShaunYearStrong
Cela peut également être dû à l'importation dans MyComponent. dans mon cas, l'erreur mentionnait MyComponent, mais en fait, une instruction import à l'intérieur provoque la rror: import {SomeLibraryCompenent} de 'some-library'
ykorach
159

vous devez exporter par défaut ou exiger (chemin) .default

var About = require('./components/Home').default
jackypan1989
la source
2
J'ai eu ce problème avec 'react-native-navbar'. J'ai appelé par défaut sur l'exigence et cela a résolu mon problème. Merci.
Varand Pezeshkian
3
Hmm, l'ajout de .default dans mon cas résout le problème. Cependant, je suis en fait en train d'exporter le composant Home extend par défaut sur cette classe, donc je m'attendais à ce qu'il fonctionne sans le '.default'
Marc
3
pouvez-vous s'il vous plaît expliquer la raison comme ce qui se passe lorsque nous ajoutons par défaut?
Subham Tripathi
1
cela a fonctionné mais quelqu'un peut-il expliquer ce que fait .default.
Burak Karasoy
1
@BurakKarasoy Vous avez besoin du .default car la façon standard dont Babel construit des modules est de transformer des export defaultinstructions en exports.defaultdonc vous devez les utiliser .defaultlorsque vous importez le module. Une façon de s'en débarrasser est d'utiliser babel-plugin-add-module-exports qui rétablit le comportement par défaut.
Jean-Baptiste Louazel
54

Vous venez de modulariser l'un de vos composants React? Si oui, vous obtiendrez cette erreur si vous avez oublié de spécifier module.exports , par exemple:

composant / code non modulaire précédemment valide:

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

composant / code modulaire avec module.exports :

module.exports = React.createClass({
    render: function() { ...
charlez
la source
2
Serait-ce la même chose pour créer la classe puis exporter? Comme votre premier extrait, puismodule.exports = YourReactComponent
Nick Pineda
3
J'ai pu simplifier ceci pour:export default class YourReactComponent extends React.Component {
cpres
Obtention de la même erreur. Je peux le rendre dans un composant mais je ne peux pas le rendre dans un autre.
Mr_Perfect
Même moi, j'ai mentionné module.exportsobtenir toujours l'erreur
Mr_Perfect
20

Si vous obtenez cette erreur, cela peut être dû au fait que vous importez un lien à l'aide

import { Link } from 'react-router'

au lieu de cela, il pourrait être préférable d'utiliser

importer {Link} à partir de ' react-router-dom '
                      ^ -------------- ^

Je crois que c'est une exigence pour la version 4 du routeur React

NSCoder
la source
Mon ami importait Link de react, au lieu de react-router-dom. Correction du problème. Jamais vu ce message d'erreur auparavant.
9
18

https://github.com/rackt/react-router/blob/e7c6f3d848e55dda11595447928e843d39bed0eb/examples/query-params/app.js#L4 Router est également l'une des propriétés de react-router. Donc, changez vos modules nécessitent du code comme ça:

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

Si vous souhaitez utiliser la syntaxe ES6 du lien use ( import), utilisez babel comme assistant.

BTW, pour faire vos travaux de code, nous pouvons ajouter {this.props.children}dans le App, comme

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

  )
}
David Guan
la source
Désolé de ne pas avoir testé soigneusement hier soir, il n'y a aucun problème dans votre composant Home. Pouvez-vous essayer ce que je viens d'éditer?
David Guan
18

Ne soyez pas surpris par la liste des réponses à une seule question. Il existe plusieurs causes à ce problème;

Pour mon cas, l'avertissement était

warning.js: 33 Avertissement: React.createElement: type n'est pas valide - attend une chaîne (pour les composants intégrés) ou une classe / fonction (pour les composants composites) mais a obtenu: undefined. Vous avez probablement oublié d'exporter votre composant à partir du fichier dans lequel il est défini. Vérifiez votre code sur index.js: 13.

Suivi de l'erreur

invariant.js: 42 Erreur non interceptée: le type d'élément n'est pas valide: attendait une chaîne (pour les composants intégrés) ou une classe / fonction (pour les composants composites) mais a obtenu: non défini. Vous avez probablement oublié d'exporter votre composant à partir du fichier dans lequel il est défini.

Je ne pouvais pas comprendre l'erreur car elle ne mentionne aucune méthode ni aucun nom de fichier. J'ai pu résoudre seulement après avoir regardé cet avertissement, mentionné ci-dessus.

J'ai la ligne suivante à l'index.js.

<ConnectedRouter history={history}>

Lorsque j'ai cherché sur Google l'erreur ci-dessus avec le mot-clé "ConnectedRouter", j'ai trouvé la solution dans une page GitHub.

L'erreur est due au fait que lorsque nous installons le react-router-reduxpackage, nous installons par défaut celui-ci. https://github.com/reactjs/react-router-redux mais pas la bibliothèque réelle.

Pour résoudre cette erreur, installez le package approprié en spécifiant la portée npm avec @

npm install react-router-redux@next

Vous n'avez pas besoin de supprimer le package mal installé. Il sera automatiquement écrasé.

Je vous remercie.

PS: Même un avertissement vous aide. Ne négligez pas l' avertissement simplement en regardant l' erreur seule.

Balasubramani M
la source
J'aimerais pouvoir voter plusieurs fois.
Cizaphil
15

Dans mon cas, l'un des modules enfants exportés ne renvoyait pas un composant de réaction approprié.

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

au lieu de

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

L'erreur indiquée était pour le parent, donc n'a pas pu comprendre.

Katti
la source
11

Dans mon cas, cela était dû à des symboles de commentaire erronés. C'est faux:

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

C'est correct:

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

Remarquez les accolades

tuanh118
la source
10

J'ai la même erreur: CORRECTION D'ERREUR !!!!

J'utilise 'react-router-redux' v4 mais elle est mauvaise .. Après npm installez react-router-redux @ next je suis sur "react-router-redux": "^ 5.0.0-alpha.9",

ET C'EST LE TRAVAIL

Thibault Jp
la source
8

J'ai obtenu cela en import App from './app/';s'attendant à ce qu'il soit importé ./app/index.js, mais à la place, il a été importé ./app.json.

tybro0103
la source
2
Et voici
sfratini
8

J'avais le même problème et j'ai réalisé que je fournissais un composant Undefined React dans le balisage JSX. Le fait est que le composant React à restituer a été calculé dynamiquement et il a fini par être indéfini!

L'erreur a déclaré:

Violation invariante: le type d'élément n'est pas valide: attendait une chaîne (pour les composants intégrés) ou une classe / fonction (pour les composants composites) mais a obtenu: non défini. Vous avez probablement oublié d'exporter votre composant à partir du fichier dans lequel il est défini. Vérifiez la méthode de rendu de C.,

L'exemple produisant cette erreur:

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>
  }
  
  // ...
}

Le problème était qu'un "uiType" non valide était fourni et que cela produisait donc undefined comme résultat:

templates['InvalidString']

cSn
la source
Je semble avoir une erreur similaire avec react-fine-uploader, mais je ne peux rien comprendre (encore). Il a un composant Gallery que j'importe et il va aussi à sa méthode de rendu mais dans cette erreur de rendu, je ne sais pas si c'est un problème de bibliothèque ou mon problème car je suis assez nouveau pour réagir.
Zia Ul Rehman Mughal
Eu une erreur similaire où il y avait une erreur dans un composant complexe. Une méthode de débogage simple consiste à simplifier temporairement le composant, par exemple const MyComponent = () => <div>my component</div>;juste pour voir si les importations fonctionnent normalement alors.
metakermit
Il serait utile de pouvoir détecter cela, par exemple avec une règle de charpie.
Will Cain le
7

Juste un ajout rapide à cela. J'avais le même problème et pendant que Webpack compilait mes tests et que l'application fonctionnait bien. Lorsque j'importais mon composant dans le fichier de test, j'utilisais la casse incorrecte sur l'une des importations et cela provoquait la même erreur.

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

Aurait du être

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

Notez que le nom d'importation myComponentdépend du nom de l'exportation à l'intérieur du MyComponentfichier.

Blackout1985
la source
7

Eu un problème similaire avec les dernières versions de React Native 0.50 et plus.

Pour moi, c'était une différence entre:

import App from './app'

et

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

(ce dernier a résolu le problème). Cela m'a pris des heures pour attraper cette nuance étrange et difficile à remarquer :(

Oleg Dater
la source
6

Une autre solution possible, qui a fonctionné pour moi:

Actuellement, react-router-reduxest en version bêta et npm renvoie 4.x, mais pas 5.x. Mais le @types/react-router-redux5.x retourné. Il y avait donc des variables non définies utilisées.

Forcer NPM / Yarn à utiliser 5.x l'a résolu pour moi.

Florian Richter
la source
6

Étant donné votre erreur de:

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

Vous avez 2 options:

  1. Votre fichier d'exportation peut avoir le mot defaultcomme dans export default class ____.... Ensuite, votre importation devra éviter de l'utiliser {}autour de lui. Un péchéimport ____ from ____

  2. Évitez d'utiliser le mot par défaut. Votre export ressemble export class ____... alors à votre import doit utiliser le {}. Commeimport {____} from ____

jasonleonhard
la source
Réponse géniale !!! +1 ... J'ai totalement export default {component name}ignoré le et j'ai oublié de l'ajouter
Si8
@ Si8 Content d'être au service et merci de m'avoir fait sourire dès le matin.
jasonleonhard
5

Dans mon cas, l'importation se faisait implicitement en raison d'une bibliothèque.

J'ai réussi à le réparer en changeant

export class Foo

à

export default class Foo.

les jours
la source
5

J'ai rencontré cette erreur lorsque j'avais un fichier .jsx et .scss dans le même répertoire avec le même nom racine.

Ainsi, par exemple, si vous avez Component.jsxet Component.scssdans le même dossier et que vous essayez de le faire:

import Component from ./Component

Webpack est apparemment confus et, au moins dans mon cas, essaie d'importer le fichier scss quand je veux vraiment le fichier .jsx.

J'ai pu le corriger en renommant le fichier .scss et en évitant toute ambiguïté. J'aurais aussi pu importer explicitement Component.jsx

bergie3000
la source
1
Vous, monsieur, sauvez des vies. Dans mon cas, c'était essentiellement Component.json (un fichier de données).
tengen
4

Et dans mon cas, il me manquait juste un point-virgule lors de l'importation-decleration dans l'un de mes sous-modules.

Corrigé en changeant ceci:

import Splash from './Splash'

pour ça:

import Splash from './Splash';
Rikard Askelöf
la source
2
OMG. Mec, tu m'as sauvé la vie. Je ne comprends vraiment pas pourquoi le constructeur ne vous le rapporte pas.
Milan Vlach
4

Dans mon cas, j'utilisais l'exportation par défaut, mais pas l'exportation d'un functionou React.Component, mais juste un JSXélément, c'est-à-dire

Erreur:

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

Travaux :

export default () => (<div>Hello World!</div>)
Andru
la source
2

En plus des import/ exportproblèmes mentionnés. J'ai trouvé que l'utilisation React.cloneElement()d'ajout propsà un élément enfant et le rendu m'ont donné cette même erreur.

J'ai dû changer:

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

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

à:

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

Voir la React.cloneElement() documentation pour plus d'informations.

Greg K
la source
2

J'ai eu cette erreur dans le routage réactif, le problème était que j'utilisais

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

mais c'était une mauvaise route qui nécessite un composant en tant que classe / fonction, donc je l'ai changé en

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

et ça a marché. (Évitez juste les accolades autour du composant)

Naxxa Consulting
la source
D'une manière différente, ma solution était l'inverse de vous, :), mais je vous remercie d'ouvrir les yeux.
Yulio Aleman Jimenez
1

Pour moi, c'est que mes composants de style ont été définis après ma définition de composant fonctionnel. Cela n'arrivait que dans la mise en scène et pas localement pour moi. Une fois que j'ai déplacé mes composants de style au-dessus de ma définition de composant, l'erreur a disparu.

Jadam
la source
1

Cela signifie que certains de vos composants importés sont mal déclarés ou inexistants

J'ai eu un problème similaire, je l'ai fait

import { Image } from './Shared'

mais quand j'ai regardé dans le fichier partagé, je n'avais pas de composant 'Image' plutôt qu'un composant 'ItemImage'

import { ItemImage } from './Shared';

Cela se produit lorsque vous copiez du code à partir d'autres projets;)

webmaster
la source
1

J'ai eu un problème avec React.Fragment, car la version de ma réaction l'était < 16.2, alors je m'en suis débarrassé.

Eugene Ihnatsyeu
la source
0

@Balasubramani M m'a sauvé ici. Je voulais en ajouter un de plus pour aider les gens. C'est le problème lorsque vous collez trop de choses ensemble et que vous êtes cavalier avec les versions. J'ai mis à jour une version de material-ui et dois changer

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

pour ça:

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';
Kyle Pennell
la source
0

J'ai eu le même problème et le problème était que certains fichiers js n'étaient pas inclus dans le regroupement de cette page spécifique. Essayez d'inclure ces fichiers et le problème peut être résolu. J'ai fait ça:

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

et cela a résolu le problème pour moi.

C'était pendant que j'utilisais React dans Dot NEt MVC

Jason
la source
0

J'ai découvert une autre raison de cette erreur. Cela a à voir avec le CSS-in-JS renvoyant une valeur nulle au JSX de niveau supérieur de la fonction de retour dans un composant React.

Par exemple:

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>
  );
}

J'obtiendrais cet avertissement:

Avertissement: React.createElement: le type n'est pas valide - attend une chaîne (pour les composants intégrés) ou une classe / fonction (pour les composants composites) mais a obtenu: null.

Suivi de cette erreur:

Erreur non interceptée: le type d'élément n'est pas valide: attendait une chaîne (pour les composants intégrés) ou une classe / fonction (pour les composants composites) mais a obtenu: null.

J'ai découvert que c'était parce qu'il n'y avait pas de CSS avec le composant CSS-in-JS que j'essayais de rendre. Je l'ai corrigé en m'assurant qu'il y avait du CSS renvoyé et non une valeur nulle.

Par exemple:

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
la source
0

Je reçois presque la même erreur:

Uncaught (promis) Erreur: le type d'élément n'est pas valide: attendait une chaîne (pour les composants intégrés) ou une classe / fonction (pour les composants composites) mais a obtenu: objet.

J'essayais d'importer un composant fonctionnel pur à partir d'une autre bibliothèque de nœuds que mon équipe a développée. Pour le corriger, j'ai dû passer à une importation absolue (référençant le chemin d'accès au composant à l'intérieur node_modules) de

importer FooBarList depuis 'team-ui';

à

importer FooBarList depuis 'team-ui / lib / components / foo-bar-list / FooBarList';

Patrick
la source
0

Dans mon cas, il a fini par être le composant externe importé comme ceci:

import React, { Component } from 'react';

puis déclaré comme:

export default class MyOuterComponent extends Component {

où un composant interne a importé le React nu:

import React from 'react';

et pointé dedans pour la déclaration:

export default class MyInnerComponent extends ReactComponent {

krayzk
la source
0

Dans mon cas, il m'a fallu beaucoup de temps pour rechercher et vérifier de nombreuses façons, mais uniquement corrigé de cette façon: supprimez "{", "}" lors de l'importation d'un composant personnalisé:

import OrderDetail from './orderDetail';

Ma mauvaise façon était:

import { OrderDetail } from './orderDetail';

Parce que dans le fichier orderDetail.js, j'ai exporté OrderDetail en tant que classe par défaut:

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

export default OrderDetail;
tiennsloit
la source