The problem is that when I try to copy a route directly I get this error:
Cannot Get / home
But when I navigate with the menu items I usually render the views, I have tried several ways as browserHistory to achieve that effect but I do not succeed, I wonder, if react-router-dom does not allow navigation directly in the URL or is it an error in my code:
// Dependencies
import React, { Component} from 'react'
import { render } from 'react-dom'
import { BrowserRouter as Router, Route, browserHistory, Link} from 'react-router-dom'
//components
class App extends Component{
render(){
return(
<div>
<h1>App!</h1>
<ul>
<li><Link to="/home"> Home</Link></li>
<li><Link to="/about"> About </Link></li>
<li><Link to="/contact"> Contact </Link></li>
</ul>
</div>
)
}
}
class Home extends Component {
render() {
return(
<h2>Home Page!</h2>
)
}
}
class About extends Component{
render() {
return(
<h2>About Page!</h2>
)
}
}
class Contact extends Component {
render() {
return(
<h2>Contact Page!</h2>
)
}
}
// routes
render(
<Router history={browserHistory}>
<div>
<Route component={App} path="/" />
<Route component={Home} path="/home" />
<Route component={About} path="/about" />
<Route component={Contact} path="/contact" />
</div>
</Router>,
document.getElementById('app')
);
I have solved it! for those who have the same error, I share what I did; to see the problem if it was from the server so I had to configure webpack with "historyApiFallback: true" or put "--historyApiCallback" in the script of webpack dev server in the package.json luck :)
Related
I have a problem with react Router.
So i am building the nav of an website and when i'm doing the routes, nothing appears.
Would you help me please to see what i'm doing wrong?
The page stays white. Nothing appears, even the root doesnt see the homepage.
........................................................................................
Homepage:
import React from 'react';
import Navbar from '../allpages/navbar/Navbar';
import {
BrowserRouter as Router, Routes, Route
} from "react-router-dom";
import Contact from "../contact/Contact";
import About from "../about/About";
const Home = () => {
return (
<>
<Router>
<Navbar />
<Routes>
<Route path="/about" element={About} />
<Route path="/contact" element={Contact} />
<Route exact path="/" element={Home} />
</Routes>
</Router>
<h3>Home</h3>
</>
)
}
export default Home
Navbar:
import React from 'react';
import {
BrowserRouter as Link
} from "react-router-dom";
const Navbar = () => {
return (
<div>
<nav>
<ul>
<li>
<Link to="/home">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/contact">Contact</Link>
</li>
</ul>
</nav>
</div>
)
}
export default Navbar
main app:
import './App.css';
import Home from './components/home/Home'
function App() {
return (
<>
<Home />
</>
);
}
export default App;
contact:
import React from 'react';
const Contact = () => {
return (
<div>
<h3>Contact</h3>
</div>
)
}
export default Contact
About:
import React from 'react';
const About = () => {
return (
<div>
<h1>About</h1>
</div>
)
}
export default About
So besides this typo:
{ BrowserRouter as Link } // use just Link
which is inside Navbar.js
I would also use recommended approach by React-Router team. Which uses <Switch> component to wrap pages. You are using Routes instead, idk if this is even valid.
You can check this example: https://v5.reactrouter.com/web/example/basic
which is really similar to your code.
What versión is you using? You might be out of dated
<React.Suspense fallback={<p>Loading...</p>}>
<Routes>
<Route path="/*" element={<Outlet />}>
<Route path="informacion-financiera" element={<Financiera />} />
<Route path="derechos-de-autor" element={<Author />} />
<Route
</Route>
</Routes>
</React.Suspense>
```
What versión is you using? You might be out of dated
<React.Suspense fallback={<p>Loading...</p>}>
<Routes>
<Route path="/*" element={<Outlet />}>
<Route path="informacion-financiera" element={<Financiera />} />
<Route path="derechos-de-autor" element={<Author />} />
<Route
</Route>
</Routes>
</React.Suspense>
```
You have browserRouter as Link so yow links are not links
There is a #/ (hashbang) in my react route...
searching online yeilds covering <Route> with the new <BrowserRouter> will fix the problem
import React, { Component } from 'react';
import './App.scss';
import { observer } from 'mobx-react';
import { Header } from './components/Header'
import { Footer } from './components/Footer';
import { Route , BrowserRouter , Switch } from 'react-router-dom';
import MainState from './components/appset/MainState';
import HomePage from './components/HomePage';
import { TestContent } from './components/TestContent';
import { Account } from './components/Account';
import { TokenList } from './components/TokenList';
import { TokenPage } from './components/TokenPage';
import ErrorPage from './components/ErrorPage';
class Layout extends Component {
render() {
return (
<div id="bodyWheel" className={`App ${MainState.currentTheme} ${MainState.currentLang}`}>
<Header />
<div id="App-intro" className={this.state.resolutionHeight}>
<div className="container">
<div className="layout-main">
<BrowserRouter>
<Route path="/" exact component={HomePage} />
<Route path="/test" component={TestContent} />
<Route path="/account/:id" exact component={Account} />
<Route path="/token" exact component={TokenPage} />
<Route path="/token/:id" exact component={TokenList} />
<Route path="/operation/:id" exact component={HomePage}/>
<Route path="/error/:id" exact component={ErrorPage} />
</BrowserRouter>
</div>
</div>
</div>
<Footer />
</div>
);
}
}
export default Layout;
It adds #/ by itself at the end of every route for example:
www.foo.com/account/tera
becomes
www.foo.come/account/tera#/
<BrowserRouter> did nothing at all.
Will building and uploading to a webserver instead of running on 'npm start' fix the problem?
(edit:) turns out <BrowserRouter> works but something just keeps adding#/to the end of my routes the routs without#/` works just fine
fix is in the <BrowserRouter> edit to <BrowserRouter basename="">
and cover the main div
<BrowserRouter basename="">
<div id="bodyWheel" className={`App ${MainState.currentTheme} ${MainState.currentLang}`}>
....
</div>
</BrowserRouter>
fixed all the routing problems!
I'm using HashRouter in my application to prevent it from breaking when a page gets refreshed, or when a user tries to navigate to a specific route (ex: mysite.com/about)
How would I go about using page jumps in a tags? Something like this:
Contact Me
just navigates back to the start page with HashRouter. Is there any way to rewrite the link to have it jump down to the specific id?
index.js
...
import { HashRouter } from 'react-router-dom';
ReactDOM.render(
<HashRouter>
<App />
</HashRouter>, document.getElementById('root'));
registerServiceWorker();
App.js
import React, { Component } from 'react';
import { Switch, Route } from 'react-router-dom';
... //import for the components
class App extends Component {
render() {
return (
<div className="App">
<TopNav />
<div className="app-container">
<SideNav />
<div className="app-content">
<Switch>
<Route exact path='/' component={Home} />
<Route path='/about' component={About} />
<Route path='/projects' component={Projects} />
...
</Switch>
</div>
</div>
<BottomNav />
</div>
);
}
}
export default App;
I'm using the latest version of React Router v4 and I'm trying to render my page components Home/About inside the PageWrap div but the problem I'm having is that if I add the Routes into my header then it will switch the routes but they will display the Home/About component as part of the header and no where I want them to be.
If I put the routes into the PageWrap then the router doesn't work but doesn't throw any errors on the console.
How can I display and switch between components in the PageBody div?
Webpack link
app.js
import React from 'react'
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
import styled from 'styled-components'
import Header from './Header'
import Home from './pages/Home'
import About from './pages/About'
const Wrapper = styled.div`
display:flex;
min-height:100vh;
flex:1;
background:#eee;
`
const PageWrap = styled.div`
margin:0 auto;
min-width:1400px;
background: #000;
`
class App extends React.Component { // eslint-disable-line react/prefer-
stateless-function
render() {
return (
<div>
<Header />
<Wrapper>
<PageWrap>
<Router>
<Switch>
<Route exact path="/login" component={Home} />
<Route exact path="/frontpage" component={About} />
<Route exact path="/logout" render={() => (<div>logout</div>)} />
</Switch>
</Router>
</PageWrap>
</Wrapper>
</div>
)
}
}
export default App
Header.js
import React from 'react'
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
import styled from 'styled-components'
import Home from '../pages/Home'
import About from '../pages/About'
import Topics from '../pages/Topics'
const Wrapper = styled.div`
width:100%;
height:100px;
background:papayawhip;
`
class Header extends React.Component { // eslint-disable-line react/prefer-
stateless-function
render() {
return (
<Router>
<Wrapper>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/topics">Topics</Link></li>
<Route exact path="/" component={Home} />
<Route exact path="/about" component={About} />
<Route path="/topics" component={Topics} />
</Wrapper>
</Router>
)
}
}
export default Header
home.js
const Home = () => (<div>Home</div>)
About.js
const About = () => (<div>About</div>)
You should only have one <Router> in your application and it should wrap all your <Route /> and <Link/> components in your component tree.
So your render method in App component should be something like this.
render() {
return (
<Router>
<div>
<Header />
<Wrapper>
<PageWrap>
<Switch>
<Route exact path="/login" component={Home} />
<Route exact path="/frontpage" component={About} />
<Route exact path="/logout" render={() => (<div>logout</div>)} />
</Switch>
</PageWrap>
</Wrapper>
</div>
</Router>)
}
And make sure to remove <Router> and all <Route>s from your Header component.
Updated WebpackBin:https://www.webpackbin.com/bins/-KiLrUNoJVxxLhL8UWx1
At some point, when you have "tens or hundreds" or routes you may want to delegate routing.
You can see that referred to here as child routing
I am trying to create a Layout component which would render the Header and Footer. So that I can later on use the Layout like
<Layout> ... </Layout>
I have used Routing in the Header and Footer, obviously. To do this, I need to use
<Router history...
<Route path...
When I do this one after the other(for header and footer: though I feel that this is wrong) in my layout.js. It works. The header and footer are shown in the browser. However, they don't work properly. On refresh the footer vanishes and sometimes both, the header and the footer. I strongly believe that rendering Router one after the other is the reason for this malfunctioning, but I can't figure out the correct approach. Moreover, I don't want to use the following snippets
header.js
import React from 'react';
import {Link} from 'react-router'
import {Navbar, NavItem} from 'react-materialize';
export default React.createClass({
render(){
return (
<div>
<Navbar brand='logo' right>
<NavItem><Link to="/Home" activeClassName="active">Home</Link></NavItem>
<NavItem><Link to="/Sign-In" activeClassName="active">Sign In</Link></NavItem>
<NavItem><Link to="/Register" activeClassName="active">Register</Link></NavItem>
</Navbar>
{this.props.children}
</div>
)
}
})
footer.js
import React, {Component} from 'react';
import {Link} from 'react-router'
import {Footer} from 'react-materialize';
import '../../resource/template.css'
class RT_Footer extends Component{
render(){
return (
<div>
{this.props.children}
<Footer copyrights="© 2015 Copyright Text"
moreLinks={
<Link className="grey-text text-lighten-4 right" href="#!">More Links</Link>
}
links={
<ul>
<li><Link to="/About Us" className="grey-text text-lighten-3">About Us</Link></li>
<li><Link to="/Terms & Conditions" className="grey-text text-lighten-3">Terms & Conditions</Link></li>
<li><Link to="/Help" className="grey-text text-lighten-3">Help</Link></li>
<li><Link to="/Contact Us" className="grey-text text-lighten-3">Contact Us</Link></li>
</ul>
}
className='example'
>
<h5 className="white-text">Footer Content</h5>
<p className="grey-text text-lighten-4">You can use rows and columns here to organize your footer content.</p>
</Footer>
</div>
);
}
}
export default RT_Footer;
layout.js
import {Router, Route, browserHistory} from 'react-router'
class Layout extends Component {
render(){
return (
<div>
<span>
<Router history={browserHistory}>
<Route path="/" component={Header}>
<Route path="/Home" component={Home}/>
<Route path="/Sign-In" component={SignIn}/>
<Route path="/Register" component={Register}/>
</Route>
</Router>
</span>
<span>
<Router history={browserHistory}>
<Route path="/" component={RT_Footer}>
<Route path="/About Us" component={About}/>
<Route path="/Terms & Conditions" component={TC}/>
<Route path="/Register" component={Register}/>
</Route>
</Router>
</span>
</div>
);
}
}
export default Layout;
Then I simply rendered Layout in index.js
I suggest that you don't render the Router component twice (I haven't checked but you probably can't).
So, how the Router component works :
You give the router an history (via the history props), here you use the browserHistory from the same library wich is fine.
Then you define all the existing routes for your application using the Route component with a path, and the component to load if the browser url match this path property.
Now, in your case I suggest you to do something like that :
app.js
import {Router, Route, browserHistory} from 'react-router'
import Layout from './components/Layout'
// Import here all the required components used by the router such as SignIn, Register, ...
render(
<Layout>
<Router history={browserHistory}>
<Route path="/" component={RT_Footer}>
<Route path="/About Us" component={About}/>
<Route path="/Terms & Conditions" component={TC}/>
<Route path="/Register" component={Register}/>
// Add as many Route components as needed
</Router>
</Layout>,
document.getElementById('react-anchor')
Then your layout file should look like this :
layout.js
import Header from './Header'
import Footer from './Footer'
import React, {Component} from 'react'
class Layout extends Component {
render() {
return (
<div>
<Header />
{this.props.children}
<Footer />
</div>
)
}
}
And in your Header and Footer component, render whatever you want, to provide link to load the requested component you can use from react-router or some other way the library offer (see their documentation)
Edit :
Careful about route Path, like "Terms & Conditions" is probably not a valid path