React Router v4 get current location

12,491

Solution 1

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'));
}); 

Solution 2

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('/');
      }
    }
});

Solution 3

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.

Share:
12,491

Related videos on Youtube

Michael Horojanski
Author by

Michael Horojanski

Updated on June 16, 2022

Comments

  • Michael Horojanski
    Michael Horojanski almost 2 years

    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.