Error no detectado: Infracción invariable: el tipo de elemento no es válido: se esperaba una cadena (para componentes integrados) o una clase / función pero se obtuvo: objeto

529

Recibo este error:

Error no detectado: Infracción invariable: El tipo de elemento no es válido: se esperaba una cadena (para componentes integrados) o una clase / función (para componentes compuestos) pero se obtuvo: objeto.

Este es mi código:

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)

Mi Home.jsxarchivo:

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
fuente
77
Por favor, eche un vistazo a stackoverflow.com/questions/36795819/…
Marcelo Salazar
Posible duplicado de ¿ Cuándo debo usar llaves para importar ES6?
Jim G.
Este error puede aumentar si intenta importar un componente inexistente . Asegúrese de no tener ningún error tipográfico y de que el componente se llame así. En el caso de las bibliotecas, asegúrese de usar la versión adecuada, ya que los componentes pueden tener diferentes nombres en diferentes versiones.
totymedli
Esto también puede suceder cuando define una propiedad, tal vez a través de la destrucción de ES6, con el mismo nombre que un componente ya importado (e intenta pasarlo a otro componente).
Philip Murphy el

Respuestas:

887

En mi caso ( usando Webpack ) fue la diferencia entre:

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

vs

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

El segundo funciona mientras que el primero está causando el error. O lo contrario.

JohnL
fuente
81
Googler del futuro aquí, ¡gracias, este fue mi problema! Tiene sentido en retrospectiva, ya que el primero está desestructurando la exportación, pero si usó por defecto, entonces solo está tratando de desestructurar una función / clase.
ebolyen
3
Para las personas futuras, mi caso fue un error tipográfico en el nombre del elemento que estaba usando. Me cambié <TabBarIOS.item>a<TabBarIOS.Item>
Ryan-Neal Mes
66
Enorme. ¿Por qué es este el caso?
lol
45
Para cualquiera que todavía se pregunte por qué esto funciona: {MyComponent} importa la exportación 'MyComponent' del archivo '../components/xyz.js' - La segunda importa la exportación predeterminada de '../components/xyz.js'.
ShaunYearStrong
También puede ser debido a la importación dentro de MyComponent. en mi caso, el error mencionó MyComponent, pero en realidad la declaración de importación dentro de él causa el error: import {SomeLibraryCompenent} de 'some-library'
ykorach
159

necesita exportar por defecto o requiere (ruta) .default

var About = require('./components/Home').default
jackypan1989
fuente
2
Tuve este problema con 'react-native-navbar'. Llamé a default en require y solucionó mi problema. Gracias.
Varand Pezeshkian
3
Hmm, agregar .default en mi caso resuelve el problema. Sin embargo, en realidad estoy exportando el componente Inicio extendido por defecto en esa clase, por lo que hubiera esperado que funcionara sin el '.default'
Marc
3
¿Puedes explicar la razón como qué sucede cuando agregamos el valor predeterminado?
Subham Tripathi
1
funcionó, pero ¿puede alguien hacer una explicación sobre lo que hace .default?
Burak Karasoy
1
@BurakKarasoy Necesita el .default ya que la forma estándar en que los módulos de compilación de Babel es transformar las export defaultdeclaraciones es exports.defaultlo que debe usar .defaultcuando importa el módulo. Una forma de deshacerse de eso es usar babel-plugin-add-module-exports que restaura el comportamiento predeterminado.
Jean-Baptiste Louazel
54

¿Acabas de modularizar alguno de tus componentes React? En caso afirmativo, obtendrá este error si olvidó especificar module.exports , por ejemplo:

componente / código no modularizado previamente válido:

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

componente / código modularizado con módulo . exportaciones :

module.exports = React.createClass({
    render: function() { ...
charlez
fuente
2
¿Sería lo mismo crear la clase y luego exportar? Como tu primer fragmento y luegomodule.exports = YourReactComponent
Nick Pineda
3
Pude simplificar esto para:export default class YourReactComponent extends React.Component {
cpres
Obteniendo el mismo error. Puedo renderizarlo en un componente pero no puedo renderizar en otro.
Mr_Perfect
Incluso mencioné que module.exportstodavía recibo el error
Mr_Perfect el
20

Si recibe este error, puede deberse a que está importando un enlace utilizando

import { Link } from 'react-router'

en cambio, podría ser mejor usar

importar {Link} desde ' react-router-dom '
                      ^ -------------- ^

Creo que este es un requisito para la versión 4 del router react

NSCoder
fuente
Mi amigo estaba importando Link desde react, en lugar de react-router-dom. Solucionado el problema. Nunca he visto este mensaje de error antes.
O-9
18

https://github.com/rackt/react-router/blob/e7c6f3d848e55dda11595447928e843d39bed0eb/examples/query-params/app.js#L4 Router también es una de las propiedades de react-router. Así que cambie sus módulos requieren un código como ese:

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

Si desea usar la sintaxis ES6, use el enlace ( import), use babel como ayudante.

Por cierto, para hacer sus obras de código, podemos añadir {this.props.children}en el App, al igual

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

  )
}
David Guan
fuente
Perdón por no probar cuidadosamente anoche, no hay ningún problema en su componente Home. ¿Puedes probar lo que acabo de editar?
David Guan
18

No se sorprenda con la lista de respuestas para una sola pregunta. Hay varias causas para este problema;

Para mi caso, la advertencia fue

warning.js: 33 Advertencia: React.createElement: el tipo no es válido: se esperaba una cadena (para componentes integrados) o una clase / función (para componentes compuestos) pero se obtuvo: indefinido. Probablemente olvidó exportar su componente desde el archivo en el que está definido. Verifique su código en index.js: 13.

Seguido por el error

invariant.js: 42 Error no detectado: el tipo de elemento no es válido: se esperaba una cadena (para componentes integrados) o una clase / función (para componentes compuestos) pero se obtuvo: indefinido. Probablemente olvidó exportar su componente desde el archivo en el que está definido.

No pude entender el error ya que no menciona ningún método o nombre de archivo. Pude resolver solo después de mirar esta advertencia, mencionada anteriormente.

Tengo la siguiente línea en index.js.

<ConnectedRouter history={history}>

Cuando busqué en Google el error anterior con la palabra clave "ConnectedRouter" , encontré la solución en una página de GitHub.

El error se debe a que, cuando instalamos el react-router-reduxpaquete, por defecto lo instalamos. https://github.com/reactjs/react-router-redux pero no la biblioteca real.

Para resolver este error, instale el paquete adecuado especificando el alcance npm con @

npm install react-router-redux@next

No necesita eliminar el paquete instalado incorrectamente. Se sobrescribirá automáticamente.

Gracias.

PD: incluso la advertencia te ayuda. No descuides la advertencia solo mirando el error solo.

Balasubramani M
fuente
Desearía poder votar esto varias veces.
Cizaphil
15

En mi caso, uno de los módulos secundarios exportados no devolvía un componente de reacción adecuado.

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

en vez de

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

El error que se muestra fue para el padre, por lo tanto no se pudo resolver.

Katti
fuente
11

En mi caso, eso fue causado por símbolos de comentarios incorrectos. Esto está mal:

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

Esto es correcto:

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

Observe las llaves

tuanh118
fuente
10

Tengo el mismo error: ERROR FIX !!!!

Uso 'react-router-redux' v4 pero es mala. Después de instalar npm react-router-redux @ next estoy en "react-router-redux": "^ 5.0.0-alpha.9",

Y ES TRABAJO

Thibault Jp
fuente
8

Estaba teniendo el mismo problema y me di cuenta de que estaba proporcionando un componente Reacción indefinida en el marcado JSX. ¡La cuestión es que el componente de reacción para renderizar se calculó dinámicamente y terminó siendo indefinido!

El error declaró:

Infracción invariable: el tipo de elemento no es válido: se esperaba una cadena (para componentes integrados) o una clase / función (para componentes compuestos) pero se obtuvo: indefinido. Probablemente olvidó exportar su componente desde el archivo en el que está definido. Verifique el método de representación de C.,

El ejemplo que produce este error:

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

El problema fue que se proporcionó un "uiType" no válido y, por lo tanto, esto estaba produciendo indefinido como resultado:

templates['InvalidString']

cSn
fuente
Parece que tengo un error similar con react-fine-uploader, pero no puedo entender nada (todavía). Tiene un componente de Galería que estoy importando y también va a su método de renderizado, pero en ese error de renderizado, no estoy seguro de si es un problema de biblioteca o mi problema, ya que soy bastante nuevo para reaccionar.
Zia Ul Rehman Mughal
Tuvo un error similar cuando hubo un error en un componente complejo. Un método de depuración simple es simplificar temporalmente el componente, por ejemplo, const MyComponent = () => <div>my component</div>;solo para ver si las importaciones funcionan normalmente en ese momento.
metakermit
Sería útil poder detectar esto, por ejemplo, con una regla de pelusa.
Will Cain
7

Solo como una rápida adición a esto. Estaba teniendo el mismo problema y mientras Webpack estaba compilando mis pruebas y la aplicación funcionaba bien. Cuando estaba importando mi componente al archivo de prueba, estaba usando el caso incorrecto en una de las importaciones y eso estaba causando el mismo error.

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

Debería haber sido

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

Tenga en cuenta que el nombre de importación myComponentdepende del nombre de la exportación dentro del MyComponentarchivo.

Apagón1985
fuente
7

Tuve un problema similar con las últimas versiones de React Native 0.50 y posteriores.

Para mí fue una diferencia entre:

import App from './app'

y

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

(este último solucionó el problema). Me tomó horas captar este extraño, difícil de notar matiz :(

Oleg Dater
fuente
6

Otra posible solución, que funcionó para mí:

Actualmente, react-router-reduxestá en beta y npm devuelve 4.x, pero no 5.x. Pero el @types/react-router-reduxregreso 5.x. Por lo tanto, se utilizaron variables indefinidas.

Obligar a NPM / Yarn a usar 5.x lo resolvió para mí.

Florian Richter
fuente
6

Dado su error de:

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

Tienes 2 opciones:

  1. Su archivo de exportación puede tener la palabra defaultcomo en export default class ____.... Entonces su importación deberá evitar su uso {}. Como enimport ____ from ____

  2. Evite usar la palabra predeterminada. Entonces su exportación se ve así. export class ____... Luego, su importación debe usar el {}. Me gustaimport {____} from ____

jasonleonhard
fuente
Respuesta impresionante !!! +1 ... pasé totalmente por alto el export default {component name}y olvidé agregarlo
Si8
@ Si8 Me alegra estar de servicio y gracias por hacerme sonreír a primera hora de la mañana.
jasonleonhard
5

En mi caso, la importación estaba sucediendo implícitamente debido a una biblioteca.

Logré arreglarlo cambiando

export class Foo

a

export default class Foo.

los días
fuente
5

Me encontré con este error cuando tenía un archivo .jsx y .scss en el mismo directorio con el mismo nombre raíz.

Entonces, por ejemplo, si tiene Component.jsxy está Component.scssen la misma carpeta e intenta hacer esto:

import Component from ./Component

Webpack aparentemente se confunde y, al menos en mi caso, trata de importar el archivo scss cuando realmente quiero el archivo .jsx.

Pude solucionarlo cambiando el nombre del archivo .scss y evitando la ambigüedad. También podría haber importado explícitamente Component.jsx

bergie3000
fuente
1
Usted señor, es un salvavidas. En mi caso, era esencialmente Component.json (un archivo de datos).
tengen
4

Y en mi caso, solo faltaba un punto y coma en la declinación de importación en uno de mis submódulos.

Se solucionó cambiando esto:

import Splash from './Splash'

a esto:

import Splash from './Splash';
Rikard Askelöf
fuente
2
Dios mio. Hombre, me salvaste la vida. Realmente no entiendo por qué el constructor no te informa esto.
Milan Vlach
4

En mi caso, estaba usando la exportación predeterminada, pero no exportaba una functiono React.Component, sino solo unaJSX elemento, es decir,

Error:

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

Trabajos :

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

Además de import/ exportproblemas mencionados. Encontré que usar React.cloneElement()para agregar propsa un elemento secundario y luego representarlo me dio el mismo error.

Tuve que cambiar:

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

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

a:

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

Vea los React.cloneElement() documentos para más información.

Greg K
fuente
2

Recibí este error en el enrutamiento de reacción, el problema era que estaba usando

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

pero era una ruta incorrecta requiere componente como clase / función, así que lo cambié a

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

Y funcionó. (Solo evite las llaves alrededor del componente)

Consultoría Naxxa
fuente
De alguna manera diferente, mi solución fue tu inverso, :), pero te agradezco que abras los ojos.
Yulio Aleman Jimenez
1

Para mí fue que mis componentes con estilo se definieron después de la definición de mi componente funcional. Solo estaba sucediendo en la puesta en escena y no localmente para mí. Una vez que moví mis componentes con estilo sobre mi definición de componente, el error desapareció.

Jadam
fuente
1

Significa que algunos de sus componentes importados se declaran incorrectamente o no existen

Tuve un problema similar, lo hice

import { Image } from './Shared'

pero cuando busqué en el archivo Compartido no tenía un componente 'Imagen' sino un Componente 'ItemImage'

import { ItemImage } from './Shared';

Esto sucede cuando copia el código de otros proyectos;)

administrador de página web
fuente
1

Tuve un problema con React.Fragment, porque la versión de mi reacción era < 16.2, así que me deshice de ella.

Eugene Ihnatsyeu
fuente
0

@Balasubramani M me salvó aquí. Quería agregar uno más para ayudar a las personas. Este es el problema cuando estás pegando demasiadas cosas y siendo arrogante con las versiones. Actualicé una versión de material-ui y necesito cambiar

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

a esto:

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
fuente
0

Tuve el mismo problema y el problema fue que algunos archivos js no se incluyeron en el paquete de esa página específica. Intente incluir esos archivos y el problema podría solucionarse. Hice esto:

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

y me solucionó el problema.

Esto fue mientras estaba usando React en Dot NEt MVC

Jason
fuente
0

He descubierto otra razón para este error. Tiene que ver con el CSS-in-JS que devuelve un valor nulo al JSX de nivel superior de la función de retorno en un componente React.

Por ejemplo:

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

Recibiría esta advertencia:

Advertencia: React.createElement: el tipo no es válido: se esperaba una cadena (para componentes integrados) o una clase / función (para componentes compuestos) pero se obtuvo: nulo.

Seguido de este error:

Error no detectado: el tipo de elemento no es válido: se esperaba una cadena (para componentes integrados) o una clase / función (para componentes compuestos) pero se obtuvo: nulo.

Descubrí que era porque no había CSS con el componente CSS-in-JS que estaba tratando de renderizar. Lo arreglé asegurándome de que se devolviera CSS y no de un valor nulo.

Por ejemplo:

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
fuente
0

Recibo casi el mismo error:

Error no detectado (en promesa): el tipo de elemento no es válido: se esperaba una cadena (para componentes integrados) o una clase / función (para componentes compuestos) pero se obtuvo: objeto.

Intenté importar un componente funcional puro de otra biblioteca de nodos que mi equipo ha desarrollado. Para solucionarlo, tuve que cambiar a una importación absoluta (haciendo referencia a la ruta al componente interno node_modules) desde

importar FooBarList desde 'team-ui';

a

importar FooBarList desde 'team-ui / lib / components / foo-bar-list / FooBarList';

Patricio
fuente
0

En mi caso, terminó siendo el componente externo importado de esta manera:

import React, { Component } from 'react';

y luego declaró como:

export default class MyOuterComponent extends Component {

donde un componente interno importó el React bare:

import React from 'react';

y punteado en él para la declaración:

export default class MyInnerComponent extends ReactComponent {

krayzk
fuente
0

En mi caso, me llevó bastante tiempo buscar y comprobar muchas formas, pero solo lo solucioné de esta manera: elimine "{", "}" al importar un componente personalizado:

import OrderDetail from './orderDetail';

Mi manera equivocada fue:

import { OrderDetail } from './orderDetail';

Porque en el archivo orderDetail.js, exporté OrderDetail como la clase predeterminada:

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

export default OrderDetail;
tiennsloit
fuente