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.
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.
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
The main issue is that you have used more than one export default keyword.
You could use:
export default App
export {home}
etc etc
Related
Im new to react and in the application im working im using a class component Summary
class SummaryList extends React.Component {
//code for the summarylist component here
}
class Summary extends React.Component {
render() {
return (
<Switch>
<Route path="/apply" component={Advance} />
<Route path="/summary/edit/:id" component={EAdvance} />
<Route path="/summary" component={SummaryList} />
</Switch>
);
}
}
export default Summary;
Im using this Summary in other page by importing it and using the component as Summary...
Now the isssue here is i need to use the SummaryList present in Summary in other place....when im trying to import Summay again....its stopped displaying the first place tried with exporting SummaryList seperately below export default Summary...by putting as export {SummaryList} and tried importing it in the second place and in the first place used Summary only....but its not working
If i need to reuse the component what shoud i do...cant i import the same component two times in my application
Yes you can export and import different components and render it multiple times.
Eg:-
App.js
import React, { Component } from 'react';
import Header from './Header';
import Main from './Main';
class App extends Component {
render() {
return (
<div>
<Header />
<Main />
</div>
);
}
}
export default App;
Header.js
import React, { Component } from 'react';
import Main from './Main';
class Header extends Component {
render() {
return (
<header>
<h1>Header Component</h1>
<Main/>
</header>
);
}
}
export default Header;
Main.js
import React, { Component } from 'react';
class Main extends Component {
render() {
return (
<main>
<p>Main Component</p>
</main>
);
}
}
export default Main;
Here Main in rendered in App.js and Header.js
I am fairly new to React and am having trouble rendering a component in App.js. After much googling I still don't know why I am just getting a blank white page in the browser instead of a printed piece of text as shown in component1.js. Here's my code:
component1.js
import React from 'react';
class component1 extends React.Component {
render() {
return (
<div>
<h1>It's a bit chilly out there</h1>
</div>
);
}
}
export default component1;
App.js
import React, { Component } from 'react';
import {component1} from './component1.js';
class App extends React.component{
render() {
return (
<div>
<component1 />
</div>
);
}
}
export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';
ReactDOM.render(
<App />,
document.getElementById('root')
);
Could anyone please steer me towards the right path and tell me what I am doing wrong here?
Thanks in advance.
Wrong case :
class App extends React.Component
------------------------↑
Also, component1 must be imported as a default import (not a named import) with a capital letter :
import Component1 from './component1.js';
I'm making a react app, I made a navbar and It renders in all of the components and I only want it visible in one, I made a HOC function but It still doesnt work correctly.
Higher Order Components
this is my navigation component
import React from 'react';
import {NavLink} from "react-router-dom";
const Navigation = () => {
return (
<div id = "navlinks">
<NavLink to = "">PROMOS</NavLink>
<NavLink to = "" >Nueva Orden</NavLink>
<NavLink to = "" >Ordenes</NavLink>
<NavLink to = "">Menú</NavLink>
<NavLink id = "logout" to = "/" >Cerrar Sesión</NavLink>
</div>
)
}
export default Navigation;
and this is is my router
import React, { Component } from 'react';
import { BrowserRouter , Route} from "react-router-dom";
import './App.css';
import Home from "./components/Home";
import Menu from "./components/Menu";
import Navigation from "./components/Navigation";
class App extends Component {
render() {
return (
<BrowserRouter>
<div>
<Navigation/>
<div>
<Route path= "/" component = {Home} exact />
<Route path= "/Menu" component = {Menu}/>
</div>
</div>
</BrowserRouter>
);
}
}
export default App;
and my HOC component
import React, { Component } from 'react';
const LoaderHOC = (WrappedComponent) => {
return class LoaderHOC extends Component{
render(){
this.props.Navigation.length === 0 ? <div className = 'Loader'></div> : <WrapperComponent {... this.props}/>
}
}
}
export default LoaderHOC;
I suppose you have a way to determine whether your user is loggedIn or not. Suppose, you have store the information in isLoggedIn variable, than you can do following to hide navigation if user is not logged in,
{ isLoggedIn && <Navigation /> }
But once your application grows, I suggest you to make different routes depending on the public/private state.
Create a PrivateRoute.js file
import React, { Component } from 'react';
import { Redirect, Route } from 'react-router-dom';
import Navigation from "./components/Navigation";
class PrivateRoute extends Component {
render() {
// use your own logic here
const isLoggedIn = !!localStorage.getItem('token');
if (!isLoggedIn) {
return <Redirect to='/' />;
}
return (
<div>
<Navigation />
// your private route
</div>
}
}
export default PrivateRoute;
create your PublicRoute.js file
import React, { Component } from 'react';
import { Redirect, Route } from 'react-router-dom';
class PublicRoute extends Component {
render() {
<div>
// your all public route
</div>
}
}
export default PublicRoute;
Now Just include those into your main file
import React, { Component } from 'react';
import { BrowserRouter , Route} from "react-router-dom";
import { PublicRoute, PrivateRoute } from './routes';
import './App.css';
import Home from "./components/Home";
import Menu from "./components/Menu";
class App extends Component {
render() {
return (
<BrowserRouter>
<div>
<PublicRoute />
<PrivateRoute />
</div>
</BrowserRouter>
);
}
}
export default App;
Don't use HOC for this.
You must have store somewhere that user is loggedIn, if not I would suggest you to use a localStorage like,
localStorage.setItem("loggedIn", true);
Note: To setup a localStorage you don't need any extra configuration.
In your router you can use this to hide your component,
{localStorage.getItem("loggedIn") && <Navigation/>}
I have a mini project in which the first page having title homepage but the next page contacts is click through link it retains the homepage as title. I've explicitly declared title as Contact Us but then also it shows Homepage.
Here's my code:
For App.js:
import React, { Component } from 'react';
import {BrowserRouter as Router, Route, Switch, Link} from 'react-router-dom';
import ContactUs from '/Users/yashchoksi/Documents/linking/src/ContactUs';
class App extends Component {
render() {
return (
<Router>
<div>
<title>HomePage</title>
<Link to="/src/ContactUs">Contact Us</Link>
<Switch>
<Route exact path="/src/ContactUs" component={ContactUs}/>
</Switch>
</div>
</Router>
);
}
}
export default App;
And for Contact Us page:
import React, { Component } from 'react';
class ContactUs extends Component {
render(){
return(
<div>
<title>ContactUs</title>
Hello From COntactUs.
</div>
);
}
}
export default ContactUs;
Please see and tell me how to declare title for dynamic naming!
You can set it in your component:
import React, { Component } from 'react';
class ContactUs extends Component {
componentDidMount() {
document.title = 'Contact Us'
}
render(){
return(
<div>
<title>ContactUs</title>
Hello From COntactUs.
</div>
);
}
}
export default ContactUs;
Just use the following code:
componentWillMount(){
document.title="Title name";
}
Edit:
componentWillMount will be deprecated in React 17, so you can use componentDidMount instead.
For better api and server rendering, use react-helmet. It is also a one-liner at its simplest.
I am trying to implement a navigation example using react router and stuck in an error. Please find the code
app.js
-------
import React from 'react';
import ReactDOM from 'react-dom';
import Routes from './routes';
ReactDOM.render(Routes, document.getElementById('react-container'));
routes.js
---------
import { React,Component } from 'react';
import { DefaultRoute, Link, Route, RouteHandler,Router } from 'react-router';
import Page1 from './page1';
import Home from './home';
export default class Routes extends Component {
constructor() {
super();
}
render() {
return (
<Router >
<Route path="/" component={Home}>
<Route name="page1" path="/1" component={ Page1 }/>
</Route>
</Router>
);
}
}
home.js
-------
import React, { Component } from 'react';
export default class Home extends Component {
constructor() {
super();
}
render() {
return (
<div>
<Header />
{this.props.children}
</div>
);
}
}
page1.js
--------
import React, { Component } from 'react';
export default class Page1 extends Component {
constructor() {
super();
}
render() {
return (
<div>
<h1> Page 1 </h1>
</div>
);
}
}
I have babel transformer to convert from es6 to es5 and I get the following error on loading the app,
Uncaught Invariant Violation: ReactDOM.render(): Invalid component element. Instead of passing a component class, make sure to instantiate it by passing it to React.createElement.
Can anyone help me in troubleshooting this issue ?
The problem is in your routes.js. You are wrapping your routes inside of a component, then passing that to ReactDOM.render. You should be passing the jsx directly. My suggestions would be to unwrap routes from your class, and just export the jsx.
routes.js
---------
import React from 'react'
import { Router, Route } from 'react-router'
import Page1 from './page1'
import Home from './home'
let routes =
<Router>
<Route path="/" component={Home}>
<Route name="page1" path="/1" component={Page1}/>
</Route>
</Router>
export default routes
The error is complaining that you are passing a class, rather then calling React.createElement. Remember that this:
let someElement = <div>Hello</div>
Will turn into this:
var someElement = React.createElement(
"div",
null,
"Hello"
)