React.createElement: tipo é inválido - esperava uma string


99

Tentando fazer com que react-router (v4.0.0) e react-hot-loader (3.0.0-beta.6) funcionem bem, mas obtendo o seguinte erro no console do navegador:

Aviso: React.createElement: type é inválido - esperava uma string (para componentes embutidos) ou uma classe / função (para componentes compostos), mas obteve: indefinido. Você provavelmente se esqueceu de exportar seu componente do arquivo em que está definido.

index.js:

import React from 'react';
import ReactDom from 'react-dom';
import routes from './routes.js';
require('jquery');
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.min.js';
import './css/main.css';

const renderApp = (appRoutes) => {
    ReactDom.render(appRoutes, document.getElementById('root'));
};

renderApp( routes() );

routes.js:

import React from 'react';
import { AppContainer } from 'react-hot-loader';
import { Router, Route, browserHistory, IndexRoute } from 'react-router';
import store from './store/store.js';
import { Provider } from 'react-redux';
import App from './containers/App.jsx';
import Products from './containers/shop/Products.jsx';
import Basket from './containers/shop/Basket.jsx';

const routes = () => (

    <AppContainer>
        <Provider store={store}>
            <Router history={browserHistory}>
                <Route path="/" component={App}>
                    <IndexRoute component={Products} />
                    <Route path="/basket" component={Basket} />
                </Route>
            </Router>
        </Provider>
    </AppContainer>

);

export default routes;

Se você usar react-router-config, certifique-se de usar a componentpropriedade em vez de render, porque o pacote não suporta o último. Veja mais no GitHub .
totymedli de

Respostas:


130

Na maioria das vezes, isso se deve a uma exportação / importação incorreta.

Erro comum:

// File: LeComponent.js
export class LeComponent extends React.Component { ... }

// File: App.js
import LeComponent from './LeComponent';

Opção possível:

// File: LeComponent.js 
export default class LeComponent extends React.Component { ... }

// File: App.js
import LeComponent from './LeComponent';

Existem algumas maneiras de estar errado, mas esse erro é devido a uma incompatibilidade de importação / exportação 60% das vezes, sempre.

Editar

Normalmente, você deve obter um rastreamento de pilha que indica uma localização aproximada de onde a falha ocorre. Isso geralmente vem logo após a mensagem que você tem em sua pergunta original.

Se não aparecer, pode valer a pena investigar o porquê (pode ser uma configuração de construção que você está perdendo). Independentemente disso, se não aparecer, o único curso de ação é restringir onde a exportação / importação está falhando.

Infelizmente, a única maneira de fazer isso, sem um rastreamento de pilha, é remover manualmente cada módulo / submódulo até não receber mais o erro e, em seguida, voltar a subir na pilha.

Editar 2

Por meio de comentários, era realmente um problema de importação, especificamente importar um módulo que não existia


Observei o traço que aponta para a linha 12 de routes.js. Essa linha é<IndexRoute component={Products} />
JoeTidee

2
Tem certeza de que a rota do índice realmente faz parte do RR4? (Tenho quase certeza que não)
Chris,

Esse era o problema - obrigado! Eu voltei para v3.0.0
JoeTidee

Ótimo, bom material. Sinta-se à vontade para marcá-la como a resposta aceita, pois ajudará futuros leitores a saber como abordar questões semelhantes
Chris,

1
@PriyaRanjanSingh É impossível dizer apenas com um pequeno comentário. Você pode postar uma nova pergunta com detalhes?
Chris

16

Eu estava recebendo esse erro também.

Eu estava usando:

import BrowserRouter from 'react-router-dom';

Em vez disso, Fix estava fazendo isso:

import { BrowserRouter } from 'react-router-dom';


11

Tente isto

npm i react-router-dom@next

em seu App.js

import { BrowserRouter as Router, Route } from 'react-router-dom'

const Home = () => <h1>Home</h1>

const App = () =>(
  <Router>
    <Route path="/" component={Home} />
  </Router>
)

export default App;


4

Tive esse problema quando adicionei um arquivo css à mesma pasta do arquivo do componente.

Minha declaração de importação foi:

import MyComponent from '../MyComponent'

o que era bom quando havia apenas um único arquivo, MyComponent.jsx. (Eu vi esse formato em um exemplo e tentei, mas esqueci que tinha feito isso)

Quando adicionei MyComponent.scss à mesma pasta, a importação falhou. Talvez o JavaScript tenha carregado o arquivo .scss e, portanto, não houve erro.

Minha conclusão: especifique sempre a extensão do arquivo, mesmo que haja apenas um arquivo, caso você adicione outro posteriormente.


3

Para futuros googlers:

Minha solução para esse problema foi atualizar reacte react-dompara suas versões mais recentes no NPM. Aparentemente, eu estava importando um componente que estava usando a nova sintaxe de fragmento e foi quebrado na minha versão anterior do React.


2

Este problema me ocorreu quando eu tinha uma referência incorreta em minha instrução render / return. (aponte para uma classe não existente). Verifique também se há referências incorretas no código da instrução de retorno.


2

Na maioria das vezes, isso indica um erro de importação / exportação. Mas tome cuidado não apenas para certificar-se de que o arquivo referenciado no rastreamento de pilha seja bem exportado, mas também de que este arquivo esteja importando outros componentes corretamente. No meu caso, o erro foi assim:

import React from 'react';

// Note the .css at the end, this is the cause of the error!
import SeeminglyUnimportantComponent from './SeeminglyUnimportantComponent.css';

const component = (props) => (            
  <div>
    <SeeminglyUnimportantComponent />
    {/* ... component code here */}
  </div>    
);

export default component;


Obrigado por este comentário! Eu tenho esse problema desde a atualização de alguns pacotes, e tenho percorrido todos esses comentários e nenhum deles está em questão neste código. Mas era isso - o arquivo com problema importa outra coisa que está causando o erro!
Diane Kaplan

2

Acho que a coisa mais importante a se perceber ao solucionar esse bug é que ele se manifesta quando você tenta instanciar um componente que não existe. Este componente não precisa ser importado. No meu caso, estava passando componentes como propriedades. Esqueci de atualizar uma das chamadas para passar corretamente o componente após alguma refatoração. Infelizmente, uma vez que JS não é digitado estaticamente, meu bug não foi detectado e levou algum tempo para descobrir o que estava acontecendo.

Para solucionar esse bug, inspecione o componente antes de renderizá-lo, para ter certeza de que é o tipo de componente que você espera.


"ele se manifesta quando você tenta instanciar um componente que não existe" - foi o que aconteceu comigo. O componente foi importado / exportado corretamente, mas eu estava passando-o como um prop por uma rota de autorização no react-router e esqueci de mudar o render={props => <Component {...props} />}para component={Component}.
deslocadotexan

2

Estava faltando um Fragmento de Reação :


function Bar({ children }) {

  return (
    <div>
     {children}
    </div>
  );
}

function Foo() {
  return (
    <Bar>
      <Baz/>
      <Qux/>
    </Bar>
  );
}

O código acima gera o erro acima. Mas isso corrige:

<Bar>
  <>
    <Baz/>
    <Qux/>
  </>
</Bar>

Aconteceu comigo quando adicionei ReactCollapsingTable ( yarn add react-collapsing-table). Consegui alternar entre este aviso (que resultou em um erro de hidratação) e uma 'janela não definida' que foi detectada dentro do módulo da tabela <div>...</div>
reativa

Eventualmente, transpilei todo o projeto desde o início (em vez de recarregar a quente) e o problema voltou a ocorrer. Encontrou a solução aqui: stackoverflow.com/a/43969990/2821963 (em vez de import module from 'module-name', use require(module-name).default)
superk

2

Matriz de componentes

Uma maneira comum de obter esse erro é usar uma matriz de componentes , com um índice posicional usado para selecionar o componente a ser renderizado da matriz. Eu vi um código como este muitas vezes:

const checkoutSteps = [Address, Shipment, Payment]

export const Checkout = ({step}) => {

  const ToRender = checkoutSteps[step]

  return (
    <ToRender />
  )
}

Isso não é necessariamente um código ruim, mas se você chamá-lo com um índice incorreto (por exemplo -1, ou 3neste caso), o ToRendercomponente estará undefined, gerando o React.createElement: type is invalid...erro:

<Checkout step={0} /> // <Address />
<Checkout step={1} /> // <Shipment />
<Checkout step={2} /> // <Payment />
<Checkout step={3} /> // undefined
<Checkout step={-1} /> // undefined

Uma solução racional

Você deve proteger você e seus colegas deste código difícil de depurar usando uma abordagem mais explícita, evitando números mágicos e usando PropTypes:

const checkoutSteps = {
  address: Address,
  shipment Shipment,
  payment: Payment
}

const propTypes = {
  step: PropTypes.oneOf(['address', 'shipment', 'payment']),
}

/* TIP: easier to maintain
const propTypes = {
  step: PropTypes.oneOf(Object.keys(checkoutSteps)),
}
*/

const Checkout = ({step}) => {

  const ToRender = checkoutSteps[step]

  return (
    <ToRender />
  )
}

Checkout.propTypes = propTypes

export default Checkout

E seu código será semelhante a este:

// OK
<Checkout step="address" /> // <Address />
<Checkout step="shipment" /> // <Shipment />
<Checkout step="payment" /> // <Payment />

// Errors
<Checkout step="wrongstep" /> // explicit error "step must be one of..."
<Checkout step={3} /> // explicit error (same as above)
<Checkout step={myWrongVar} /> // explicit error (same as above)

Benefícios desta abordagem

  • o código é mais explícito , você pode ver claramente o que deseja renderizar
  • você não precisa se lembrar dos números e seus significados ocultos ( 1é para Endereço, 2 é para ...)
  • erros são explícitos também
  • sem dor de cabeça para seus colegas :)

1

O que faltou para mim era que eu estava usando

import { Router, Route, browserHistory, IndexRoute } from 'react-router';

em vez disso, a resposta correta deve ser:

import { BrowserRouter as Router, Route } from 'react-router-dom';

Claro, você precisa adicionar o pacote npm react -router-dom :

npm install react-router-dom@next --save

1

No meu caso, esqueci de importar e exportar meus (novos) elementos chamados pelo render no arquivo index.js.


0

No meu caso, a ordem em que você cria o componente e renderiza é importante. Eu estava renderizando o componente antes de criá-lo. A melhor maneira é criar o componente filho e, a seguir, os componentes pai e, a seguir, renderizar o componente pai. Alterar o pedido resolveu o problema para mim.


0

No meu caso, apenas precisei atualizar de react-router-reduxpara react-router-redux@next. Estou assumindo que deve ter sido algum tipo de problema de compatibilidade.


0

Em palavras simples, de alguma forma o seguinte está acontecendo:

render() {
    return (
        <MyComponent /> // MyComponent is undefined.
    );
}

Pode não estar necessariamente relacionado a alguma importação ou exportação incorreta:

render() {
    // MyComponent may be undefined here, for example.
    const MyComponent = this.wizards[this.currentStep];

    return (
        <MyComponent />
    );
}

0

Se você tiver esse erro ao testar um componente, certifique-se de que cada componente filho seja renderizado corretamente quando executado sozinho. Se um de seus componentes filho depender de recursos externos para renderizar, tente simular com jest ou qualquer outro lib de simulação:

Exemplo:

jest.mock('pathToChildComponent', () => 'mock-child-component')

0

No meu caso, o erro ocorreu ao tentar usar ContextApi. Eu usei por engano:

const MyContext = () => createContext()

Mas deveria ter sido definido como:

const MyContext = createContext()

Estou postando aqui para que futuros visitantes que ficarem presos em um erro tão idiota possam ajudá-lo a evitar horas de dor de cabeça, porque isso não é causado por importação / exportação incorreta.


0

A dependência circular é também uma das razões para isso. [em geral]


0

Este é um erro que de alguma forma teve que depurar. Como já foi dito muitas vezes, a importação / exportação inadequada pode causar esse erro, mas surpreendentemente recebi esse erro de um pequeno bug no react-router-dom authentication setupmeu caso abaixo:

CONFIGURAÇÃO ERRADA:

const PrivateRoute = ({ component: Component, ...rest }) => (
    <Route
        {...rest}
        render={(props) => (token ? <Component {...props} /> : <Redirect to={{ pathname: "/login" }} />)}
    />
);

CONFIGURAÇÃO CORRETA:

const PrivateRoute = ({ component: Component, token, ...rest }) => (
    <Route
        {...rest}
        render={(props) => (token ? <Component {...props} /> : <Redirect to={{ pathname: "/login" }} />)}
    />
);

A única diferença era que eu estava desconstruindo o tokenno PrivateRoute component. A propósito, o token é obtido localstoragedessa const token = localStorage.getItem("authUser");forma, então se ele não estiver lá eu sei que o usuário não está autenticado. Isso também pode causar esse erro.


0

É muito simples, na verdade. Tive esse problema quando comecei a codificar o React, e o problema quase sempre é porque a importação:

import React, { memo } from 'react';

Você pode usar a desestruturação porque o react lib tem uma propriedade como memo, mas você não pode desestruturar algo assim

import { user } from 'assets/images/icons/Profile.svg';

porque não é um objeto.

Espero que ajude!


0

React.Fragment

consertou o problema para mim

Erro de código:

 return (
            <section className={classes.itemForm}>
             <Card>
             </Card> 
            </section>
      );

Consertar

 return (
      <React.Fragment>
        <section className={classes.itemForm}>
         <Card>
         </Card> 
        </section>
      </React.Fragment>
  );

0

Não é necessário um problema direto relacionado à importação / exportação. No meu caso, eu estava renderizando um elemento filho dentro de um elemento pai e o elemento filho tem elemento / tag jsx que é usado, mas não importado. Eu importei e usei então ele consertou o problema. Portanto, o problema estava nos elementos jsx que estão dentro do elemento filho, NÃO na exportação do próprio elemento filho.


-1

Acabei de passar 30 minutos tentando resolver esse problema básico do BASIC.

Meu problema era que eu estava importando elementos nativos reac

por exemplo import React, { Text, Image, Component } from 'react';

E tentando usá-los, o que me levou a receber este erro.

Uma vez que eu mudar de <Text>para <p>e <Image>para <img>tudo funcionou como esperado.


-1

Eu estava recebendo este erro e nenhuma das respostas era meu caso, isso pode ajudar alguém a pesquisar:

Eu estava definindo um Proptype errado:

ids: PropTypes.array(PropTypes.string)

Deveria ser:

ids: PropTypes.arrayOf(PropTypes.string)

VSCode e o erro de compilação não me deram uma dica correta.


-2

EDITAR

Você está complexificando o processo. Basta fazer isso:

index.js:

import React from 'react';
import ReactDom from 'react-dom';
import routes from './routes.js';
require('jquery');
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.min.js';
import './css/main.css';

ReactDom.render(<routes />, document.getElementById('root'));

routes.js:

import React from 'react';
import { AppContainer } from 'react-hot-loader';
import { Router, Route, browserHistory, IndexRoute } from 'react-router';
import store from './store/store.js';
import { Provider } from 'react-redux';
import App from './containers/App.jsx';
import Products from './containers/shop/Products.jsx';
import Basket from './containers/shop/Basket.jsx';

const routes =
    <AppContainer>
        <Provider store={store}>
            <Router history={browserHistory}>
                <Route path="/" component={App}>
                    <IndexRoute component={Products} />
                    <Route path="/basket" component={Basket} />
                </Route>
            </Router>
        </Provider>
    </AppContainer>;

export default routes;

Tem certeza que o problema vem daqui? E não das próprias páginas?
John Smith,
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.