title: React-Router - Update BrowserHistory without a Refresh of the Page
body: <p>I've run into unique problem w/ the react-router - I say unique because I haven't been able to find anything in the documentation. </p>
  
  <p><strong>Works Great:</strong></p>
  
  <p>When a user loads the below react application at the <code>/</code> route, they are redirected to the <code>/locations/random</code> route which then triggers an API <code>GET</code> request in the <code>shouldComponentUpdate</code> block. Once the data are retrieved and stored in the <code>LocationStore</code> component, there is an event emitted to the <code>Dashboard</code> component to render a new row with that retrieved data. All well and good.</p>
  
  <p><strong>Problem Area:</strong></p>
  
  <p>After the data are retrieved and stored in the <code>LocationStore</code>, I want to grab the <code>id</code> property of the data <code>data.id</code> and put that value into the current visible url, i.e. <code>locations/100</code> and not <code>locations/random</code> so a user can navigate back in the future, but when I do <code>browserHistory.push('locations/100');</code> it hits the <code>Router</code> again and the whole process begins again which means the same data are being retrieved again. Is there a way to update the visible URL and save it in <code>browserHistory</code> without triggering the <code>Router</code>? Or is there a way to create a new <code>Route</code> like <code>&lt;Route path="/locations/random" hiddenFromHistory=true component={Dashboard}/&gt;</code>? </p>
  
  <pre><code>import React from 'react'
  import { render } from 'react-dom'
  import { Router, Route, browserHistory, IndexRedirect} from 'react-router'
  import {isInteger} from 'lodash'
  
  let _data = {};
  let _changeListeners = [];
  
  render((
      &lt;Router history={browserHistory}&gt;
          &lt;Route path="/" component={App}&gt;
              &lt;IndexRedirect to="/locations/random"/&gt;
              &lt;Route path="/locations/:locationId" component={Dashboard}/&gt;
          &lt;/Route&gt;
      &lt;/Router&gt;
  ), document.getElementById('app'));
  
  const App = React.createClass({
      render() {
          return &lt;div&gt;Home&lt;/div&gt;
      }
  });
  
  const Dashboard = React.createClass({
  
      getInitialState: function () {
          return {
              data: {}
          }
      },
  
      updateData(){
          // Once the LocationStore has sent out a notification that the data has changed, trigger a render of the dashboard
          this.setState({
              data: LocationStore.getData()
          });
      },
  
      shouldComponentUpdate (nextProps) {
          // Trigger a request to load new data when the url changes
          LocationStore.getLocation(nextProps.params);
          return true;
      },
  
      componentDidMount() {
          LocationStore.addChangeListener(this.updateData);
      },
  
      componentWillUnmount() {
          LocationStore.removeChangeListener(this.updateData);
      },
  
      render() {
          return (
              &lt;div&gt;
                  &lt;div className="page-container" style={{ paddingBottom: 20}}&gt;
                      &lt;div className="col-lg-12"&gt;
                          &lt;h2&gt;Display Data Here as a Row&lt;/h2&gt;
                      &lt;/div&gt;
                  &lt;/div&gt;
              &lt;/div&gt;
          )
      }
  });
  
  const LocationStore = {
  
      getLocation: function (params) {
          // Get location by id or random
          const isRandom = !isInteger(params.locationId);
          var url = (isRandom) ? "/api/locations/random" : `/api/locations/${params.locationId}`;
          Utils.getJSON(url, function (err, res) {
              _data = res;
  
              // If the user hit the random route, update the URL here to show the id of the record brought down
              if (isRandom) {
                  const path = `/locations/${_data.id}`;
                  browserHistory.push(path);
              }
  
              LocationStore.notifyChange();
          })
      },
  
      getData: function () {
          return _data;
      },
  
      notifyChange: function () {
          _changeListeners.forEach(function (listener) {
              listener()
          })
      },
  
      addChangeListener: function (listener) {
          _changeListeners.push(listener)
      },
  
      removeChangeListener: function (listener) {
          _changeListeners = _changeListeners.filter(function (l) {
              return listener !== l
          })
      }
  };
  
  const Utils = {
      getJSON: function (url, cb) {
          const req = new XMLHttpRequest();
          req.onload = function () {
              if (req.status === 404) {
                  cb(new Error('not found'))
              } else {
                  cb(null, JSON.parse(req.response))
              }
          };
          req.open('GET', url);
          req.send()
      }
  };
  </code></pre>
  
  <p><strong>Working Update:</strong></p>
  
  <pre><code>/* ./LocationStore */
  if (isRandom) {
      _isLoadingRandomLocation = true;
      const path = `/locations/${_data.id}`;
      browserHistory.replace(path)      
  }
  
  /* ./Dashboard */
  componentWillReceiveProps(nextProps){
      // When the URL params change get locations
      if (nextProps.params !== this.props.params) {
          if (LocationStore.getIsLoadingRandomLocation()) {
              LocationStore.setIsLoadingRandomLocation(false);
          }
          else {
              LocationStore.getLocation(nextProps.params);
          }
      }
  },
  </code></pre>