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 .
Related
routing_page..
i used 2 switch statement first for Route and second for PrivateRoute..
and after login and getting token in local storage....when i visit to the privateroute it shows blank page only.....
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import LoginPage from "./Pages/Login_page";
import {Route,Switch,BrowserRouter as Router} from "react-router-dom";
import SignupPage from "./Pages/signup_page";
import Noting_page from "./Pages/home_notingPage";
import INdividualNotes from './Pages/allNotesOfUser';
import Editing_page from './Pages/editingPage';
import PrivateRoute from './components/private';
ReactDOM.render(
<Router>
<Switch>
<Route exact path="/login"><LoginPage/></Route>
<Route path="/signup"><SignupPage/></Route>
<Switch>
<PrivateRoute path="/notes" component={INdividualNotes}/>
<PrivateRoute path="/home" component={Noting_page}/>
<PrivateRoute path="/login/edit" component={Editing_page}/>
</Switch>
</Switch>
</Router>,
document.getElementById('root')
);
Private.js
i am using token here for auth
import { render } from "#testing-library/react";
import React, { useEffect, useState } from "react";
import { Route ,useHistory,Redirect, useLocation, Switch} from "react-router-dom";
function PrivateRoute({component:component,...rest}){
return(
<Route {...rest}
render={ props=>
localStorage.getItem("token")?
<component {...props}/>
:
<Redirect to={{pathname:"/login",state:{from:props.location}}}/>
} />)
}
export default PrivateRoute;
I think it is something related to the naming convention of components. Your component is written in small letters. If you just change {component: Component} in PrivateRoute file and then where you using your component <component> replace this with <Component>, It will render the page. Perhaps it is not mentioned anywhere in official docs or maybe it is happening due to react-router plugin.
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>
);
}
I have a component that imports a Router and it isn't working and there isn't any error message. The pages aren't appearing on the browser. It is a course s' app. Because of the fact that this course is a bit old, some things could be overpast. Here are the codes of my components:
import '../common/template/dependencies'
import React from 'react'
import Routes from './Routes'
export default props => (
<div className='wrapper'>
<div className='content-wrapper'>
<Routes />
</div>
</div>
)
The component Routes.js that does the routing:
import React from 'react'
import {Router, Route , Redirect, hasHistory} from 'react-router'
import Dashboard from '../dashboard/Dashboard'
import BillingCycle from '../billingCycle/BillingCycle'
export default props => (
<Router history={hasHistory}>
<Route path='/' component={Dashboard} />
<Route path='/billingCycles' component={BillingCycle} />
<Redirect from='*' to='/' />
</Router>
)
When I comment this line of the component above, everything works well.
{/*<Routes />*/}
import React from 'react'
import {BrowserRouter as Router, Route, Redirect, Switch} from 'react-router-dom';
import Dashboard from './DashBoard';
import BillingCycle from './BillingCycle'
export default props => (
<Router>
<Switch>
<Route exact path='/' component={Dashboard}/>
<Route exact path='/billingCycles' component={BillingCycle}/>
<Redirect from='*' to='/'/>
</Switch>
</Router>
)
Check your code does hasHistory is available in new version react-router.
Also you should use react-router-dom.
Hope this helps..
Use react-router-dom
Change your import in Route.js like this:
import {BrowserRouter as Router, Route} from 'react-router-dom'
I am currently experimenting with the use of React Router on the website I am building. I came across the use of React Router in order to navigate through my website, and also do other things like read parameter values etc. However, I find it to be slightly confusing. You see, on my administrator login page, the router only works some times - but I haven't really figured out when and when not. I am using this.props.history.push('/admin/dashboard'), which I believe is the correct way of doing it. This is currently my setup in index.js where i have all my routes:
import React from 'react';
import ReactDOM from 'react-dom';
import registerServiceWorker from './registerServiceWorker';
import './css-styling/styling.css'
import Frontpage from './Frontpage';
import { BrowserRouter, Route, Router, Switch, Link, NavLink } from 'react-router-dom';
import AdminLogin from './Admin-Login';
import AdminWelcome from './Admin-Welcome';
import Authentication from './components/Authentication';
const websiteRoutes = (
<Router history={history}>
<div>
<Switch>
<Route path="/" component={Frontpage} exact={true}/>
<Route path="/admin" component={AdminLogin} exact={true}/>
<Authentication props={this.props}>
<Route path="/admin/welcome" component={AdminWelcome} exact={true}/>
</Authentication>
</Switch>
</div>
</Router>
);
var appRoot = document.getElementById('root');
registerServiceWorker();
ReactDOM.render(websiteRoutes, appRoot);
And each 'component' has its structure like this:
import React from 'react';
import ReactDOM from 'react-dom';
import AdminHeader from './components/Admin-Header';
import AdminPanelLogin from './components/Admin-Panel-Add-News';
import history from './components/History';
class AdminLogin extends React.Component{
render() {
return(
<div>
<AdminHeader />
<AdminPanelLogin />
</div>
);
}
}
export default AdminLogin;
What seem to be the problem here? I have tried a lot of different solutions, without having any luck. One of them was creating this 'global history', which you can see that I have imported in my AdminAddNews class.
What is the correct way of using React Router in my case?
By the way; The history.push happens inside my AdminPanelLogin component, where the code looks like this:
import React from 'react';
import ReactDOM from 'react-dom';
import { Icon, Input, Button, Message } from 'semantic-ui-react';
import {auth} from './Firebase';
import {NotificationContainer, NotificationManager} from 'react-notifications';
import { withRouter, Redirect } from 'react-router-dom';
import history from './components/History';
class AdminLogin extends React.Component{
constructor(props){
super(props);
this.handleLogin = this.handleLogin.bind(this);
this.clickLogin = this.clickLogin.bind(this);
this.performLogin = this.performLogin.bind(this);
}
handleLogin(e){
this.setState({
[e.target.name]: e.target.value
});
}
clickLogin(e){
e.preventDefault();
auth.signInWithEmailAndPassword(this.state.email, this.state.password).then(() => {
this.props.history.push('/admin/dashboard');
}).catch((error)=> {
})
}
render() {
return (
<HTMLGOESHERE>
);
}
}
export default AdminLogin;
Few things, that you need to correct,
First: In your Routes you have passed history but you have not created a custom history anywhere. You can simply use BrowserRouter for now.
Second: Write your authentication component as Wrapper to your Routes instead of using your Routes as children to it
Authentication:
const PrivateRoute = (props) => {
const userKey = Object.keys(window.localStorage)
.filter(it => it.startsWith('firebase:authUser'))[0];
const user = userKey ? JSON.parse(localStorage.getItem(userKey)) : undefined;
if (user) {
return <Route {...props} />
} else {
return <Redirect to='/admin'/>
}
}
export default PrivateRoute;
Now you Routes can be
import { BrowserRouter as Router, Route, Router, Switch } from 'react-router-dom';
import Authentication from './Authentication';
const websiteRoutes = (
<Router>
<div>
<Switch>
<Route path="/" component={Frontpage} exact={true}/>
<Route path="/admin" component={AdminLogin} exact={true}/>
<Authentication path="/admin/welcome" component={AdminWelcome} exact={true}/>
</Switch>
</div>
</Router>
);
Apart from this check how to Programmatically Navigate with react-router
Actually, you have to use browserHistory, which is a function of react-router.I hope following snippet will help you,
Import react-router in your index.js
import {Router, Route, browserHistory} from 'react-router';
ReactDOM.render(
<Router history={browserHistory} >
<Route path="/admin/somethingZero" component={somethingZero} />
<Route path="/admin/somethingOne" component={somethingOne}/>
</Router> , document.getElementById("root")
)
you can navigate between the components, by using browserHistory.push function
clickLogin(){
browserHistory.push('/admin/dashboard')
}
Also, go on with this tutorial, it will give better understanding of routers.
Failed prop type: The prop history is marked as required in Router, but its value is undefined.
Index.js
import {render} from 'react-dom';
import {Provider} from 'react-redux';
import { Router, browserHistory } from 'react-router';
import Sstore from './store/configureStore.js';
import routes from './routes';
import {loadMovies} from './actions/movieActions.js';
const store = Sstore;
store.dispatch(loadMovies());
render(
<Provider store={store}>
<Router history={browserHistory} routes={routes} />
</Provider>,
document.getElementById('app')
);
Route.js
import React from 'react';
import { Route, IndexRoute } from 'react-router';
import Home from './components/Home.js';
export default (
<Route path="/" component={Home}>
</Route>
);
This is the correct link to react-router-redux v4 example. You have to use ConnectedRouter from react-router-redux and pass history. I configured my project yesterday based on this example and it works fine.
In React router v4, your configuration should be something like below.
import { BrowserRouter, Route, Switch } from 'react-router-dom';
<Provider store={createStoreWithMiddleware(reducers)}>
<BrowserRouter>
<div>
<Switch>
<Route path="/api/:id" component={ComponentOne} />
<Route path="/" component={Home} />
</Switch>
</div>
</BrowserRouter>
</Provider>
The API has been changed since the previous version. Also note that the order matters. Keep the most specific paths at the top.
In my project, I get rid of this type of error in two steps:
step in to import import createBrowserHistory from 'history/createBrowserHistory'; and declaring const customHistory = createBrowserHistory(); like this:
import { BrowserRouter as StaticRouter, Router, Switch, Route, Link } from 'react-router-dom';
import createBrowserHistory from 'history/createBrowserHistory';
const customHistory = createBrowserHistory();
It looks like that it is necessary to add history attribute to the Router:
<Router history={customHistory}>
<div>
<Link to={'/.../' + linkName1}>
{itemName1}
</Link>
<Link to={'/.../' + linkName2}>
{itemName2}
</Link>
</div>