React router changes url but not view

You need to specify the attribute exact for your indexRoute, otherwise for even /details route it will still match with / . Also try to import Route from react-router-dom

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Route } from 'react-router-dom';
import Users from "./components/Users";

import Details from "./components/Details";

ReactDOM.render((
  <BrowserRouter>
    <div>
        <Route exact path="/" component={Users} />
        <Route path="/details" component={Details} />
    </div>
  </BrowserRouter>
), document.getElementById('app'))

UPDATE:

Another thing that you need to do is to attach your component Users with withRouter. You need to make use of withRouter only when your component is not receiving the Router props,

This may happen in cases when your component is a nested child of a component rendered by the Router or you haven't passed the Router props to it or when the component is not linked to the Router at all and is rendered as a separate component from the Routes.

In Users.js add

import {withRouter} from 'react-router';

.........
export default withRouter(Users)

DOCS


You just have to wrap the components inside withRouter.

<Route exact path="/mypath" component={withRouter(MyComponent)} />

Here is a sample App.js file:

...
import { BrowserRouter as Router, Route, Switch, withRouter } from "react-router-dom";
import Home from "./pages/Home";
import Profile from "./pages/Profile";

class App extends Component {
  render() {
    return (
      <Router>
        <Switch>
          <Route exact path="/" component={withRouter(Home)} />
          <Route exact path="/profile" component={withRouter(Profile)} />
        </Switch>
      </Router>
    );
  }
}

export default App;

Additional

If you are using react router, componentWillReceiveProps will get called whenever the url changes.

componentWillReceiveProps(nextProps) {
    var currentProductId = nextProps.match.params.productId;
    var nextProductId = nextProps.match.params.productId; // from the new url
    ...
}

Note

Alternatively, you may also wrap the component in withRouter before exporting, but then you have to ensure a few other things. I usually skip this step.

export default withRouter(Profile)