I have just started using react-router V4 and I want to know how to get current location of router
This is my source code
import {Meteor} from 'meteor/meteor';
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import createHistory from 'history/createBrowserHistory'
import {Route, BrowserRouter as Router, Switch} from 'react-router-dom'
import {Tracker} from 'meteor/tracker';
import Signup from '../imports/ui/signUp';
import Link from '../imports/ui/link';
import Login from '../imports/ui/login';
import NotFound from '../imports/ui/notFound';
const history = createHistory();
const unauthenticatedPages = ['/', '/signup'];
const authenticatedPages = ['/links'];
const routes = (
<Router history={history}>
<Switch>
<Route exact path="/" component={Login}/>
<Route exact path="/signup" component={Signup}/>
<Route path="/links" component={Link}/>
<Route component={NotFound}/>
</Switch>
</Router>
);
Tracker.autorun(() => {
const unlisten = history.listen((location, action) => {
// location is an object like window.location
console.log(action, location.pathname, location.state)
})
const isAuthenticated = !!Meteor.userId();
console.log('location: ', location.pathname);
//const pathName =
});
Meteor.startup(() => {
ReactDOM.render(routes, document.getElementById('app'));
});
I tried according to react-router documentation to use history but I didn't get the location.
How to get current location of a route?
I don't use redux and I will appreciate an answer without it.
Thanks, Michael.
Use the useLocation() hook to get the current route with React Router, e.g. const location = useLocation() . The hook returns the current location object. For example, you can access the pathname as location. pathname .
Use the window object to get the current URL in React, e.g. window. location. href returns a string containing the whole URL. If you need to access the path, use window.
A <Route> element tries to match its path to the current history location (usually the current browser URL). However, a location with a different pathname can also be passed for matching.
React router does partial matching, so /users partially matches /users/create , so it would incorrectly return the Users route again! The exact param disables the partial matching for a route and makes sure that it only returns the route if the path is an EXACT match to the current url.
You can use the withrouter
HOC for this. It will re-render the wrapped component anytime the route changes. Here's an example -
import {Meteor} from 'meteor/meteor';
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import createHistory from 'history/createBrowserHistory'
import {Route, BrowserRouter as Router, Switch} from 'react-router-dom'
import {withRouter} from 'react-router'
import {Tracker} from 'meteor/tracker';
import Signup from '../imports/ui/signUp';
import Link from '../imports/ui/link';
import Login from '../imports/ui/login';
import NotFound from '../imports/ui/notFound';
const history = createHistory();
const unauthenticatedPages = ['/', '/signup'];
const authenticatedPages = ['/links'];
const
ChangeTracker = withRouter(({match, location, history}) => {
console.log(action, location.pathname, location.state);
return false;
}),
routes = (
<Router history={history}>
<Switch>
<Route exact path="/" component={Login}/>
<Route exact path="/signup" component={Signup}/>
<Route path="/links" component={Link}/>
<Route component={NotFound}/>
</Switch>
<ChangeTracker />
</Router>
);
Meteor.startup(() => {
ReactDOM.render(routes, document.getElementById('app'));
});
Excellent help thanks - to keep live updating whether you're on an authenticated page or not, you could modify ChangeTracker as follows:
const ChangeTracker = withRouter(({match, location, history}) => {
const pathName = location.pathname;
isUnauthenticatedPage = unauthenticatedPages.includes(pathName);
isAuthenticatedPage = authenticatedPages.includes(pathName);
return false;
});
and your Tracker.autorun could look like:
Tracker.autorun(()=>{
const isAuthenticated = !!Meteor.userId();
if (isAuthenticated){
if (isUnauthenticatedPage){
history.push('/links');
}
}else{
if (isAuthenticatedPage) {
history.push('/');
}
}
});
You can get your current location from react router v4 by history.location
and for the pathname you can use history.location.pathname
. you can find more details about it in the official react router docs on githubReact Router Training.
So your code should be like this:
import {Meteor} from 'meteor/meteor';
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import createHistory from 'history/createBrowserHistory'
import { Route, Router, Switch } from 'react-router-dom'
import {Tracker} from 'meteor/tracker';
import Signup from '../imports/ui/signUp';
import Link from '../imports/ui/link';
import Login from '../imports/ui/login';
import NotFound from '../imports/ui/notFound';
const history = createHistory();
const unauthenticatedPages = ['/', '/signup'];
const authenticatedPages = ['/links'];
const routes = (
<Router history={history}>
<Switch>
<Route exact path="/" component={Login}/>
<Route exact path="/signup" component={Signup}/>
<Route path="/links" component={Link}/>
<Route component={NotFound}/>
</Switch>
</Router>
);
Tracker.autorun(() => {
const isAuthenticated = !!Meteor.userId();
const pathname = history.location.pathname;
//Now you can do whatever you want here
});
Important! passing history as props to BrowserRouter makes warning because by default BrowserRouter uses its version of history and ignores the history you passed, so to prevent this warning you should use { Router } from 'react-router-dom'
rather than BrowserRouter
and everything works in the way you expect.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With