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;
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
Try this
npm i react-router-dom@next
in your 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;
I was getting this error as well.
I was using:
import BrowserRouter from 'react-router-dom';
Fix was doing this, instead:
import { BrowserRouter } from 'react-router-dom';
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.
For future googlers:
My solution to this problem was to upgrade react
and react-dom
to their latest versions on NPM. Apparently I was importing a Component that was using the new fragment syntax and it was broken in my older version of React.
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
This issue has occurred to me when I had a bad reference in my render/return statement. (point to a non existing class). Also check your return statement code for bad references.
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'
In my case, the order in which you create the component and render, mattered. I was rendering the component before creating it. The best way is to create the child component and then the parent components and then render the parent component. Changing the order fixed the issue for me.
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.
I was getting this error and none of the responses was my case, it might help someone googling:
I was defining a Proptype wrong:
ids: PropTypes.array(PropTypes.string)
It should be:
ids: PropTypes.arrayOf(PropTypes.string)
VSCode and the compile error didnt give me a correct hint.
In simply words, somehow the following is happening:
render() {
return (
<MyComponent /> // MyComponent is undefined.
);
}
It may not necessarily be related with some incorrect import or export:
render() {
// MyComponent may be undefined here, for example.
const MyComponent = this.wizards[this.currentStep];
return (
<MyComponent />
);
}
If you have this error when testing a component, make sure that every child component render correctly when run alone, if one of your child component depend on external resources to render, try to mock it with jest or any other mocking lib:
Exemple:
jest.mock('pathToChildComponent', () => 'mock-child-component')
Most of the time this indicates an import/export error. But be careful to not only make sure the referenced file in the stack trace is well exported itself, but also that this file is importing other components correctly. In my case the error was like this:
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;
In my case, the error occurred when trying to use ContextApi. I have mistakenly used:
const MyContext = () => createContext()
But it should have been defined as:
const MyContext = createContext()
I am posting it here so that future visitors who get stuck on such a silly mistake will get it helpful to avoid hours of headache, coz this is not caused by incorrect import/export.
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;
I just spent 30 minutes trying to solve this BASIC basic issue.
My problem was I was importing react native elements
eg import React, { Text, Image, Component } from 'react';
And trying to use them, which caused me to receive this error.
Once I switch from <Text>
to <p>
and <Image>
to <img>
everything worked as expected.
来源:https://stackoverflow.com/questions/42813342/react-createelement-type-is-invalid-expected-a-string