93

New to react.js and trying to following tutorial. Unfortunately the code given in the page didn't work. webpack complained

ERROR in ./App.jsx
Module build failed: SyntaxError: Only one default export allowed per module.

Wonder how to fix it. Thanks.

=== App.jsx====

import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, Link, browserHistory, IndexRoute  } from 'react-router'

class App extends React.Component {
   render() {
      return (
         <div>
            <ul>
               <li><Link to = "/home">Home</Link></li>
               <li><Link to = "/about">About</Link></li>
               <li><Link to = "/contact">Contact</Link></li>
            </ul>

           {this.props.children}
         </div>
      )
   }
}

export default App;

class Home extends React.Component {
   render() {
      return (
         <div>
            <h1>Home...</h1>
         </div>
      )
   }
}

export default Home;

class About extends React.Component {
   render() {
      return (
         <div>
            <h1>About...</h1>
         </div>
      )
   }
}

export default About;

class Contact extends React.Component {
   render() {
      return (
         <div>
            <h1>Contact...</h1>
         </div>
      )
   }
}

export default Contact;

=== main.js ===

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';

ReactDOM.render(<App/>, document.getElementById('app'));

UPDATE1

I commented out all the export default and added the following at the end

module.exports = {
    App: App,
    Home: Home,
    About: About,
    Contact: Contact
}

Now there is no compile error but the web page is a blank. I am not sure what is wrong here.

packetie
  • 4,839
  • 8
  • 37
  • 72
  • 2
    Possible duplicate of [Multiple React components in a single module](https://stackoverflow.com/questions/30762734/multiple-react-components-in-a-single-module) – Chris Sep 04 '17 at 15:16
  • @Chris I checked out the link and tried to make some changes and it is still not working, see the `update1` section. Thx. – packetie Sep 04 '17 at 15:21

3 Answers3

197

You can have only one default export which you declare like:

export default App; or export default class App extends React.Component {...

and later do import App from './App'

If you want to export something more you can use named exports which you declare without default keyword like:

export {
  About,
  Contact,
}

or:

export About;
export Contact;

or:

export const About = class About extends React.Component {....
export const Contact = () => (<div> ... </div>);

and later you import them like:

import App, { About, Contact } from './App';

EDIT:

There is a mistake in the tutorial as it is not possible to make 3 default exports in the same main.js file. Other than that why export anything if it is no used outside the file?. Correct main.js :

import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, Link, browserHistory, IndexRoute  } from 'react-router'

class App extends React.Component {
...
}

class Home extends React.Component {
...
}


class About extends React.Component {
...
}


class Contact extends React.Component {
...
}


ReactDOM.render((
   <Router history = {browserHistory}>
      <Route path = "/" component = {App}>
         <IndexRoute component = {Home} />
         <Route path = "home" component = {Home} />
         <Route path = "about" component = {About} />
         <Route path = "contact" component = {Contact} />
      </Route>
   </Router>

), document.getElementById('app'))

EDIT2:

another thing is that this tutorial is based on react-router-V3 which has different api than v4.

Tomasz Mularczyk
  • 34,501
  • 19
  • 112
  • 166
  • Thanks for the tip, the problem is, I don't where the `import App` etc are called in the compiler (webpack). Any ideas? – packetie Sep 04 '17 at 15:44
  • I don't know that, but why would you be concerned about it? In order to make your code work you must have one `default export` and others (if in the same file) have to be named. – Tomasz Mularczyk Sep 04 '17 at 15:46
  • I am very new to this and trying to follow the tutorial. All the previous sections in the tutorial are fine. Any idea how to make the route work as shown there? – packetie Sep 04 '17 at 15:52
  • I believe there is mistake in the tutorial because it is not possible to make 3 default exports in the same `main.js` file. Please first move each component class to distinct file like `Contact.jsx` etc. and in each file make `export default Contact;` etc. – Tomasz Mularczyk Sep 04 '17 at 15:54
  • Moved the sections of Home, About, Contact into their .jsx files. Don't see a compile error but the web page is blank. Any ideas? – packetie Sep 04 '17 at 15:58
  • @packetie in what file you have `ReactDOM.render((` ... ? – Tomasz Mularczyk Sep 04 '17 at 16:03
  • in `main.js`. Thx – packetie Sep 04 '17 at 16:04
  • I added `import Home from './Home.jsx'; import About from './About.jsx'; import Contact from './Contact.jsx';` in the main.js and now I see a different error (on browser dev console): `index.js:35950 Uncaught ReferenceError: React is not defined` – packetie Sep 04 '17 at 16:07
  • @packetie If you use JSX syntax then you need to `import React from 'react'` on top of each file. – Tomasz Mularczyk Sep 04 '17 at 16:09
  • I used your edit on main.js (that has everything) and browser gives error `index.js:9733 Uncaught TypeError: Cannot read property 'location' of undefined at new Router (index.js:9733) at index.js:29354` – packetie Sep 04 '17 at 16:13
  • what version of react-router do you use? – Tomasz Mularczyk Sep 04 '17 at 16:16
  • The version is 4.2.0 – packetie Sep 04 '17 at 16:18
  • react-router v4 has completely different api :) make a downgrade `npm install react-router@3.0.5` which is the main version this tutorial is based on. – Tomasz Mularczyk Sep 04 '17 at 16:19
  • You are absolutely right! @tomasz ! After changing to route@3.0.5, it works beautifully. Please update your answer and I'd love to accept it. – packetie Sep 04 '17 at 16:22
  • Thanks a lot @tomasz ! Accepted it. – packetie Sep 04 '17 at 16:41
5

When you

import App from './App.jsx';

That means it will import whatever you export default. You can rename App class inside App.jsx to whatever you want as long as you export default it will work but you can only have one export default.

So you only need to export default App and you don't need to export the rest.

If you still want to export the rest of the components, you will need named export.

https://developer.mozilla.org/en/docs/web/javascript/reference/statements/export

iboss
  • 456
  • 6
  • 18
3

The main issue is that you have used more than one export default keyword.

You could use:

 export default App
 export {home}
 etc etc 
JW Geertsma
  • 857
  • 3
  • 13
  • 19