React Router stop working after upgrade React - reactjs

I upgrade React from v16.0.0 to the last version to use Hook, after the upgrade, React Router stop working.
This is the AppRoute code:
import React from 'react';
import { Router, Route, Switch } from 'react-router-dom';
import createHistory from 'history/createBrowserHistory';
import DashboardPage from '../components/DashboardPage';
import HelpPage from '../components/HelpPage';
import NotFoundPage from '../components/NotFoundPage';
import LoginPage from '../components/LoginPage';
import PrivateRoute from './PrivateRoute';
import PublicRoute from './PublicRoute';
export const history = createHistory();
const AppRouter = () => (
<Router history={history}>
<div>
<Switch>
<PublicRoute path="/" component={LoginPage} exact={true} />
<PrivateRoute path="/dashboard" component={DashboardPage}/>
<Route path="/help" component={HelpPage} />
<Route component={NotFoundPage} />
</Switch>
</div>
</Router>
);
export default AppRouter;
I'm getting:
Output
thank you very much!
Ori

The Router Component in react-router-dom is actually called BrowserRouter not Router , so change Router import and Tag to BrowserRouter or Just Provide an alias and it should work without changing the tag
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
and instead of createHistory use createBrowserHistory
import { createBrowserHistory } from "history";
export const history = createBrowserHistory();
Refrence here
CodeSandbox here

Try not combining logic with UI
// ...code...
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
// ...code...
const AppRouter = () => {
const [loggedIn, setLoggedIn] = useState(false)
return (
<Router>
<Switch>
{
!loggedIn
? <Route exact path="/" component={LoginPage} />
: <Route exact path="/dashboard" component={DashboardPage}/>
}
<Route exact path="/help" component={HelpPage} />
<Route component={NotFoundPage} />
</Switch>
</Router>
);
}

Related

One router work but other router not work

Hey i have a reactjs app with this as app.tsx
import tw from 'twin.macro';
import { hot } from 'react-hot-loader/root';
import { Route, BrowserRouter as Router, Routes as Switch } from 'react-router-dom';
import Main from './Main';
import Test from './Test';
const App = () => {
return (
<><Main /><div css={tw`mx-auto w-auto`}>
<Router>
<Switch>
<Route path="/element" element={<Test />} />
<Route path="/" element={<Main />} />
</Switch>
</Router>
</div></>
);
};
export default hot(App);
But when i run a ./node_modules/.bin/webpack --watch --progress the localhost/ work but localhost/element not work i have a 404 error
Not Found The requested URL was not found on this server
Can you tell me why its not work?
(i use 6.2.1 of react-router-dom)
first and foremost you need to mention the version you are using , and try this if it works for u :-
your components should look like this, to work:-
import tw from 'twin.macro';
import { hot } from 'react-hot-loader/root';
import { Route, Routes} from 'react-router-dom';
import Main from './Main';
import Test from './Test';
const App = () => {
return (
<><Main /><div css={tw`mx-auto w-auto`}>
<Routes>
<Route exact path="/element" element= {<Test />} />
<Route exact path="/" element= {<Main/>} />
</Routes>
</div></>
);
};
NB: try to wrap your index.tsx component with the <BrowserRouter> </BrowserRouter> like this :
import { BrowserRouter } from "react-router-dom";
ReactDOM.render( <BrowserRouter> <App/> </BrowserRouter>, document.getElementById('root'))
therefore you can remove the BrowserRouter from the app.tsx
I think you're using ‘react-router-dom’ newer version. Switch is no longer in the new version. please read here
Switch' is not exported from 'react-router-dom'
import { Route, BrowserRouter as Router, Routes as Switch } from 'react-router-dom';
function App() {
const Main = () => {
return (
<h1>Main</h1>
)
}
const Test = <h1>Test</h1>
return (
<div >
<Router>
<Switch>
<Route path="/element" element={<Main />} />
<Route path="/" element={Test} />
</Switch>
</Router>
</div>
);
}
export default App;
You need to use the <Main /> structure

React router not matching any route, always goes to 404 route

React router can't match any route and always shows last (NotFound) component. Everything works fine if I use BrowserRouter from 'react-router-dom' instead of Router. But I have to use Router because I have to use custom history (for which I am using history library). Heres my code.
import { Router, Route, Switch } from 'react-router-dom';
import { createBrowserHistory } from 'history';
import ExpenseDashboardPage from '../components/ExpenseDashboardPage';
import AddExpensePage from '../components/AddExpensePage';
import EditExpensePage from '../components/EditExpensePage';
import HelpPage from '../components/HelpPage';
import NotFound from '../components/NotFound';
import Header from '../components/Header';
import LoginPage from '../components/LoginPage';
export let history = createBrowserHistory();
function AppRouter() {
return (
<div>
<Router history={history}>
<Header />
<Switch>
<Route path="/" component={LoginPage} exact={true} />
<Route path="/dashboard" component={ExpenseDashboardPage} />
<Route path="/create" component={AddExpensePage} />
<Route path="/edit/:id" component={EditExpensePage} />
<Route path="/help" component={HelpPage} />
<Route component={NotFound} />
</Switch>
</Router>
</div>
);
}
export default AppRouter;
It looks like react-router-dom version 5.x is not compatible with history version 5.0.0. I switched to history version 4.x and now its working as expected.
I know this doesn't fit the question but in my case, i included a different component in Switch component. Switch component should only have Route components in them.

React Router with custom history not working

When I was using BrowserRouter from react-router-dom, My Routes were working. But to use custom history, I replaced BrowserRouter with Router from react-router. After that my Route components are not loading properly but the url is changing properly.
Here is my codes:
AppRouter-JS:----
import React from 'react';
import { Router, Route, Switch} from 'react-router';
// import { BrowserRouter as Router,Route, Switch} from 'react-router-dom';
import {createBrowserHistory} from 'history'
import Header from '../components/Header.js';
import Dashboard from '../components/DashboardPage.js'
import CreateExpense from '../components/CreateExpensePage.js';
import EditExpense from '../components/EditExpensePage.js';
import Help from '../components/HelpPage.js';
import PageNotFound from '../components/PageNotFound.js'
import LoginPage from '../components/LoginPage.js'
export const history = createBrowserHistory();
const AppRouter = ()=>(
<Router history={history}>
<div>
<Header/>
<Switch>
<Route path='/' exact={true} component={LoginPage}/>
<Route path='/dashboard' component={Dashboard}/>
<Route path='/create' component={CreateExpense} />
<Route path="/edit/:id" component={EditExpense}/>
<Route path='/help' component={Help} />
<Route component={PageNotFound}/>
</Switch>
</div>
</Router>
)
export default AppRouter;
HeaderJS:-- (Here we have the NavLinks)
import React from 'react';
import {NavLink, Link} from 'react-router-dom';
import {connect} from 'react-redux';
import {LogoutAction} from '../Redux/Actions/AuthActions.js'
export const Header = ({logoutAction})=>(
<header>
<h1>Expense Tracker</h1>
<p><NavLink exact activeClassName='active-class' to='/'>Home Page</NavLink></p>
<p><NavLink activeClassName='active-class' to='/create'>Add Expense</NavLink></p>
<p><NavLink activeClassName='active-class' to='/help'>Help Page</NavLink></p>
<button onClick={logoutAction}>Logout</button>
</header>
);
const mapDispatchToProps = (dispatch)=> {
return {
logoutAction: ()=> dispatch(LogoutAction())
}
}
export default connect(undefined,mapDispatchToProps) (Header);
After clicking any NavLink or Link it always opens the PageNotFound component.
I actually just found my problem, and it might be yours too.
I was on react-router-dom#5.2.0 and history#5.0.0.
react-router 5x is compatible with history 4x. Once I downgraded to history#4.10.1 everything started working.
Now using useNavigate() hook instead of useHistory() or anything related to history.
You can use like this;
import { useNavigate } from "react-router-dom";
let navigate = useNavigate();
navigate('/detail')
Note:Written to update information.
i used history.goBack("/signup") not history.push("/signup") seems to work for me .

How to get Google Analytics to work with React

I'm trying to track each page but google only registers a view each time I click the refresh button. Not when iv'e routed to a new path. Anyone got an Idea on how to make this work?
import React, {useEffect} from 'react';
import { BrowserRouter, Switch, Route } from "react-router-dom";
import OurWork from "./ourWork/ourWork"
import Home from "./home/Home"
import Packages from "./packages/Packages"
import Contacts from "./contact/Contact"
import ReactGA from 'react-ga'
import createHistory from 'history/createBrowserHistory'
const Routes = () => {
const {
ContactPage
} = Contacts();
const history = createHistory()
history.listen(location => {
ReactGA.set({ page: location.pathname });
ReactGA.pageview(location.pathname);
});
useEffect(() => {
ReactGA.pageview(window.location.pathname + window.location.search)
}, [history])
return(
<BrowserRouter history={history}>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/ourwork" exact component={OurWork} />
<Route path="/packages" exact component={Packages} />
<Route path="/Contact" exact component={ContactPage} />
</Switch>
</BrowserRouter>
)
}
export default Routes;
Looks like the same issue which is described here. Try to change <BrowserRouter history={history}> to <Router history={history}> and import Router from the "react-router-dom", like this:
import React, {useEffect} from 'react';
import { Router, Switch, Route } from "react-router-dom";
import OurWork from "./ourWork/ourWork"
import Home from "./home/Home"
import Packages from "./packages/Packages"
import Contacts from "./contact/Contact"
import ReactGA from 'react-ga'
import createHistory from 'history/createBrowserHistory'
const Routes = () => {
const {
ContactPage
} = Contacts();
const history = createHistory()
history.listen(location => {
ReactGA.set({ page: location.pathname });
ReactGA.pageview(location.pathname);
});
useEffect(() => {
ReactGA.pageview(window.location.pathname + window.location.search)
}, [history])
return(
<Router history={history}>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/ourwork" exact component={OurWork} />
<Route path="/packages" exact component={Packages} />
<Route path="/Contact" exact component={ContactPage} />
</Switch>
</Router>
)
}
export default Routes;

Conversion from React Router V2.x to V4.x

After updating React Router V2.x on V4.x, all routes go to the main page.
Here is the route on V2.x:
import {Router, Route, hashHistory } from 'react-router'
const routes = <Route component={App}>
<Route path="/results" component={Results} />
<Route path="/" component={Voting} />
</Route>;
ReactDOM.render(
<Router history={hashHistory}>{routes}</Router>,
document.getElementById('app')
);
And these are routes on V4.x:
index.jsx file:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
import App from './components/App';
import Voting from './components/Voting';
import Results from './components/Results';
const withAppLayout = Component => props => <App><Component {...props} /></App>
const routes = <Switch>
<Route exact path="/" component={withAppLayout(Voting)} />
<Route path="/results" component={withAppLayout(Results)} />
</Switch>;
ReactDOM.render(
<Router component={App}>
{routes}
</Router>,
document.getElementById('app')
);
App.jsx File:
import React from 'react';
import {List} from 'immutable';
const pair = List.of('Trainspotting', '28 Days Later');
export default React.createClass({
render: function () {
console.log(this.props.children);
return React.cloneElement(this.props.children, {pair: pair});
}
});
Voting.jsx File:
import React from 'react';
import PureRenderMixin from 'react-addons-pure-render-mixin';
import Winner from './Winner';
import Vote from './Vote';
export default React.createClass({
mixins: [PureRenderMixin],
render: function () {
return <div>
{this.props.winner ?
<Winner ref="winner" winner={this.props.winner} /> :
<Vote {...this.props} />
}
</div>;
}
});
Results.jsx File:
import React from 'react';
import PureRenderMixin from 'react-addons-pure-render-mixin';
export default React.createClass({
mixins: [PureRenderMixin],
render: function () {
return <div>Hello from results!</div>
}
});
How to fix this error?
One thing would be to use :
<Route exact path="/" component={withAppLayout(Voting)} />
The exact will make sure that only that exact path is going to match. But if you have the path="/" after the others, the others should match first though. Is this the real code you're using ?
Edit: See a complete version below.
import {BrowserRouter, Route, Switch} from 'react-router-dom'
ReactDOM.render(
<BrowserRouter>
<Switch>
<Route exact path="/" component={Voting} />
<Route path="/results" component={Results} />
</Switch>
</BrowserRouter>,
document.getElementById('app')
);
Then, if that works out, you can move the Switch part into an App Component. Also, if you want to use hash history, you need to use a HashRouter that basically initializes a Router with a hash history.

Resources