Routing not working in reactjs application - react-router

I have created a reactjs app having three pages (components), App, Login and Register, where I need to navigate from page to page by entering the url in the browser but the navigation is not working for me. Entering any url just shows me the 'App' page.
following is the code that I have written in main.js file of the app and the url that I am using to navigate looks something like this http://localhost:8080/#/login or http://localhost:8080/#/reg
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Route, NavLink, Redirect, Switch, hashHistory} from 'react-router-dom'
import App from './../jsx/App.jsx';
import Login from './../jsx/Login.jsx';
import Register from './../jsx/Register.jsx';
ReactDOM.render((
<Router history={hashHistory}>
<div>
<Route path="/" component={App}/>
<Route path="/login" component={Login}/>
<Route path="/reg" component={Register}/>
</div>
</Router>
), document.getElementById('app'))

You need to configure the route to match the root path exactly. Try this...
<Route exact path="/" component={App}/>

Remove / from your path in Route path in
<Route path="/login" component={Login}/>
<Route path="/reg" component={Register}/>
try this it's working for me
entry class
import React from 'react';
import ReactDOM from 'react-dom';
import Layout from './Component/Layout.jsx';
import { Router, Route, IndexRoute, hashHistory } from "react-router";
import Archives from './Component/Archives.jsx';
import Settings from './Component/Settings.jsx';
import Featured from './Component/Featured.jsx';
ReactDOM.render(
<Router history={hashHistory}>
<Route path="/" component={Layout}>
//<IndexRoute component={Featured}></IndexRoute>
<Route path="archives" name="archives" component={Archives}></Route>
<Route path="settings" component={Settings}></Route>
<Route path="featured" component={Featured}></Route>
</Route>
</Router>,
document.getElementById('app'));
Layout class
{
render{
return(
<div>
{this.props.children}
<ul>
<li><Link to="archives">archives</Link></li>
<li><Link to="settings">settings</Link></li>
<li><Link to="featured">featured</Link></li>
</ul>
</div>
);
}
}

If you are using react router 4, then that looks fine. However, you can try using a as shown below:
<BrowserRouter>
<Switch>
<Route path="/" component={Home} />
</Switch>
</BrowserRouter>
This is in latest versions of react. The Home component is as below:
render() {
return (
<div>
<p>Header Section</p>
<Header/>
<p>Home component</p>
<Link to="/search">search</Link>
<Route path="/search" component={Search}/>
</div>
);
}
So most probably what you need to do is to just add a switch. Other solutions may be possible too. Hope this helps :)

Use BrowserRouter and Switch from 'react-router-dom'
if you use BrowserRouter no need to pass history as props as it handles itself.
Try this.
<Router>
<Switch>
<Route exact path="/" component={App}/>
<Route exact path="/login" component={Login}/>
<Route exact path="/reg" component={Register}/>
</Switch>
</Router>

Related

Main content wrapper best practices

I want to create a main content wrapper so I don't have to add classes to each component separately, I use tailwindCSS. It is just a couple of classes, mainly to give the content a margin, a max width and keep it centered.
I put a couple of divs encompasing the routes, but I don't know if this is considered a good practise.
Here is my App.jsx
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
// pages
import Navbar from './Navbar';
import Home from './Home';
import About from './About';
import Contact from './Contact';
function App() {
return (
<Router>
<div className='font-mono'>
<Navbar />
<div className='flex justify-center'>
<div className='m-10 lg:max-w-4xl'>
<Routes>
<Route path='/' element={<Home />}/>
<Route path='/about' element={<About />} />
<Route path='/contact' element={<Contact />} />
</Routes>
</div>
</div>
</div>
</Router>
);
}
export default App;
Yeah I imagine this is pretty common. I typically abstract it in a separate component.
/components/container/Container.js
export default function Container({ children }) {
return (
<div className='flex justify-center'>
<div className='m-10 lg:max-w-4xl'>{children}</div>
</div>
);
}
You can then import it and use it wherever you'd like. In the case of wrapping your routes I suppose you won't be reusing it elsewhere, but it does still remove some visual noise and keep things a little organized.
/App.js
import Container from './components/container/Container';
function App() {
return (
<Container>
<Router>
<Routes>
<Route path='/' element={<Home />}/>
<Route path='/about' element={<About />} />
<Route path='/contact' element={<Contact />} />
</Routes>
</Router>
</Container>
);
}

React-router-Link not working->On clicking The link The URL is updated as per but page is not rendered, I have already put exact in route [duplicate]

This question already has answers here:
Link tag inside BrowserRouter changes only the URL, but doesn't render the component
(2 answers)
Closed 9 months ago.
the code goes as below,
import './App.css';
import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom'
import Home from './Pages/Home';
import About from './Pages/About';
import Notfound from './Pages/Notfound';
function App() {
return (
<Router>
<div className="App">
<nav>
<ul>
<li><Link to="/" >Home</Link></li>
<li><Link to="/about">About</Link></li>
</ul>
</nav>
<Switch>
<Route exact path='/' component={Home} />
<Route path='/about' component={About} />
<Route component={Notfound} />
</Switch>
</div>
</Router>
);
}
export default App;
Few things needs to be fixed,
Route should be defined inside Routes.
<Routes>
<Route ... />
...
...
</Routes>
Latest react-router-dom API has changed Route accepts component in the element prop not component.
<Route exact path="/" element={<Home />} />
Dependency versions
"react": "18.0.0",
"react-dom": "18.0.0",
"react-router-dom": "6.3.0",
"react-scripts": "4.0.0"

React Router + GH Pages, refresh breaking app

This isn't happening on my local server,
but when I push my create-react-app to gh-pages and try to reload anything besides the home page, or navigate directly to a routed page, the page breaks and the URL repeatedly grows looking like this...
https://hellocentral.live/about/?p=/&q=p=/~and~q=p=/~and~q=p=/~and~q=p=/~and~q=p=/~and~q=p=/~and~q=p=/~and~q=p=/~and~q=p=/~and~q=p=/~and~q=p=/~and~q=p=/~and~q=p=/~and~q=p=/~and~q=p=/~and~q=p=/~and~q=p=/~and~q=p=/~and~q=p=/~and~q=p=/....
Here is my file with my routes...
import React from "react";
import "./SiteContainer.scss";
import HeaderContainer from "../HeaderContainer/HeaderContainer";
import { Route, Switch } from "react-router-dom";
import About from "../About/About";
import Home from "../Home/Home";
import Music from "../Music/Music";
import Footer from "../Footer/Footer";
import Merch from "../Merch/Merch";
import Pics from "../Pics/Pics";
import Contact from "../Contact/Contact";
export const SiteContainer = () => {
return (
<div className="site-container">
<HeaderContainer />
<Switch>
<Route path="/about" component={About} />
<Route path="/merch" component={Merch} />
<Route path="/music" component={Music} />
<Route path="/pics" component={Pics} />
<Route path="/contact" component={Contact} />
<Route path="/" component={Home} />
</Switch>
<Footer />
</div>
);
};
export default SiteContainer;
here is my repo
https://github.com/monstaro/hc3/tree/master/src
The site is https://www.hellocentral.live
Any help would be appreciated!
You need to wrap the Switch component in a Router component. To do this, you need to import it from the react-router-dom package:
import { HashRouter as Router } from 'react-router-dom'
...
<Router basename={process.env.PUBLIC_URL}>
<Switch>
...
</Switch>
</Router>
I gave HashRouter as example because GH Pages does not support the other router, BrowserRouter. Probably, MemoryRouter or StaticRouter do work, but I am not sure.
Since your domain is https://www.hellocentral.live, you need to set segmentCount to 0 here.
Guess you're using an older version of rafgraph/spa-github-pages cited in a blog or something. I would recommend updating index.html with the latest version of the script and 404.html with this script.
From the docs,
Note that if you are setting up a Project Pages site and not using a custom domain (i.e. your site's address is username.github.io/repo-name), then you need to set pathSegmentsToKeep to 1 in the 404.html file in order to keep /repo-name in the path after the redirect.

React Router - Take over at root URL

So I've got React Router set up and I'm trying to run it from WordPress.
The app routes correctly as long as you start from the root "/". However if you manually navigate to any subpage via the address bar, React Router seems to only take over from there.
For example.
Hitting / will render the homepage. If you click the link 'style-guide' it will correctly route you to /style-guide and render the page.
However, if you manually navigate to /style-guide in your address bar, react will render the homepage there, and if you now click the style-guide link it will bring you to /style-guide/style-guide
What I need to do is tell react-router to always start from the root URL.
My Routes Look Like this
import {
BrowserRouter as Router,
Route,
Redirect,
Switch,
} from 'react-router-dom'
import PageContainer from 'containers/pageContainer'
class RoutesList extends React.Component {
render() {
return (
<Router>
<div>
<Switch>
<Route path="/" component={PageContainer} />
<Route path="style-guide" component={PageContainer} />
<Route
render={() => {
return <Redirect to="/" />
}}
/>
</Switch>
</div>
</Router>
)
}
}
export default RoutesList
Make your routes exact paths
<Route exact path="/" component={PageContainer} />
<Route exact path="/style-guide" component={PageContainer} />

Basename not working properly

I'm attempting to use a basename with react-router as documented on the react-router docs. This is due to base href being deprecated.
Here is what I have now:
import { Route, Router, useRouterHistory } from 'react-router';
import { createHistory } from 'history';
import { render } from 'react-dom';
var history = useRouterHistory(createHistory)({
basename: '/subdirectory'
});
render(
<Router history={history}>
<Route path='/' component={App}>
<Route path='next' component={Next} />
</Route>
</Router>,
document.getElementById('root')
);
When I go to http://the-url.com/subdirectory the page loads as expected (rendering the App component). However, when going to http://the-url.com/subdirectory/next, I get a 404 error. My nginx config is:
location /subdirectory {
alias /path/to/index.html;
index index.html;
try_files $uri $uri/ /path/to/index.html;
}
Here is how I managed to get it to work
Set Router basename to your subdirectory like this
<Router basename="/subdirectory">
If you used create-react-app and are building using npm run build you need to set homepage in package.json for the paths to be correct in the production build
homepage: "{http://www.the-url.com/subdirectory}"
For the nginx config, let's assume your index.html is under /path/to/subdirectory/index.html. Then the following should work
location /subdirectory {
root /path/to;
try_files $uri $uri/ /subdirectory/index.html;
}
I solved it by using:
import { Router, useRouterHistory } from 'react-router'
import createBrowserHistory from 'history/lib/createBrowserHistory'
const history = useRouterHistory(createBrowserHistory)({
basename: '/',
})
<Router history={history}>
I think the issue was different versions of the history package. react-router#2.2.4 uses history#2.1.2, while history is already at 4.5.1.
So make sure you install the correct version of the history package.
Using BrowserRouter
helpers/history.js
import { createBrowserHistory } from "history";
export default createBrowserHistory();
index.js
import {BrowserRouter as Router} from "react-router-dom";
import history from "helpers/history";
.....
<Router history={history} basename={'/app'}>
...
</Router>
Using Router
helpers/history.js
import { createBrowserHistory } from "history";
export default createBrowserHistory({ basename: '/app' });
index.js
import {Router} from "react-router-dom";
import history from "helpers/history";
....
<Router history={history}>
...
</Router>
This is too sad that react documentation does not specify anything regarding basename in react router v6. however, I tried something and it worked. please find below solution. cheers!
<HashRouter>
<Routes>
<Route path='/app'> {/* put url base here and nest children routes */}
<Route path='path1' element={ <Somecomponent1 /> } />
<Route path='path2' element={ <Somecomponent2 /> } />
</Route>
<Route path="/*" element={<Navigate to="/app/path1" />} /> {/* navigate to default route if no url matched */}
</Routes>
</HashRouter>
<HashRouter>
<Routes>
<Route path='/app'> {/* put url base here and nest children routes */}
<Route path='path1' element={ <Somecomponent1 /> } />
<Route path='path2' element={ <Somecomponent2 /> } />
</Route>
<Route path="/*" element={<Navigate to="/app/path1" />} /> {/* navigate to default route if no url matched */}
</Routes>
</HashRouter>
I was struggling this issue from 2 days approx. This article was very helpful for me.