React.createElement: type is invalid — expected a

2019-01-17 19:28发布

Trying to get react-router (v4.0.0) and react-hot-loader (3.0.0-beta.6) to play nicely, but getitng the following error in the browser console:

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in.

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;

11条回答
We Are One
2楼-- · 2019-01-17 19:38

You need to be aware of named export and default export. See When should I use curly braces for ES6 import?

In my case, I fixed it by changing from

import Provider from 'react-redux'

to

import { Provider } from 'react-redux'
查看更多
The star\"
3楼-- · 2019-01-17 19:41

In my case I just had to upgrade from react-router-redux to react-router-redux@next. I'm assuming it must have been some sort of compatibility issue.

查看更多
何必那么认真
4楼-- · 2019-01-17 19:42

I had this problem when I added a css file to the same folder as the component file.

My import statement was:

import MyComponent from '../MyComponent'

which was fine when there was only a single file, MyComponent.jsx. (I saw this format in an example and gave it a try, then forgot I'd done it)

When I added MyComponent.scss to the same folder, the import then failed. Maybe JavaScript loaded the .scss file instead, and so there was no error.

My conclusion: always specify the file extension even if there is only one file, in case you add another one later.

查看更多
该账号已被封号
5楼-- · 2019-01-17 19:42

EDIT

You are complexifying the process. Just do this :

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;
查看更多
叼着烟拽天下
6楼-- · 2019-01-17 19:50

Most of the time this happens is because you haven't exported / imported correctly.

Common error:

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

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

// no "default" export, should be  export default class LeComponent

There a few ways it could be wrong, but that error is because of an import/export mistake 60% of the time, everytime.

Edit

Typically you should get a stacktrace that indicates an approximate location of where the failure occurs. This generally follows straight after the message you have in your original question.

If it doesn't show, it might be worth investigating why (it might be a build setting that you're missing). Regardless, if it doesn't show, the only course of action is narrowing down where the export/import is failing.

Sadly, the only way to do it, without a stacktrace is to manually remove each module/submodule until you don't get the error anymore, then work your way back up the stack.

Edit 2

Via comments, it was indeed an import issue, specifically importing a module that didn't exist

查看更多
成全新的幸福
7楼-- · 2019-01-17 19:51

What missing for me was I was using

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

instead or correct answer should be :

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

Ofcourse you need to add npm package react-router-dom:

npm install react-router-dom@next --save
查看更多
登录 后发表回答