17

Switched to router v4 and history v4.5.1 and now history listener not working

import createBrowserHistory from 'history/createBrowserHistory'
const history = createBrowserHistory()

history.listen((location, action) => {
  console.log(action, location.pathname, location.state)  //  <=== Never happens
})

render(
  <Provider store={store}>
    <Router history={history}>
      ...
    </Router>
  </Provider>,
  document.getElementById('root')
)

Any ideas why it is being ignored?

ilyo
  • 35,851
  • 46
  • 106
  • 159
  • What's the Router you are using here? is that BrowserRouter or Router? I'm asking this because some people import BrowserRouter with named import like this. `import { BrowserRouter as Router } from 'react-router-dom'` – Tharaka Wijebandara May 21 '17 at 10:53
  • ^ This is what I am doing – ilyo May 21 '17 at 10:55

3 Answers3

15

Since you are using BrowserRouter(with import alias Router as mentioned in comments of the question), it doesn't care the history prop you pass in. Instead of that it internally creates and assigns new browser history to the Router. So the history instance that you listen and being used in Router is not the same. That's why your listener doesn't work.

Import the original Router.

import { Router } from 'react-router-dom';

It will work as you expect.

Tharaka Wijebandara
  • 7,955
  • 1
  • 28
  • 49
3

The problem is that you are creating your own history object and passing it into the router. However, React Router v4 already provides this object for you, via this.props. (Importing Router has nothing to do with this)

componentDidMount() {
    this.props.history.listen((location, action) => console.log('History changed!', location, action));
}

You may need to layer your app a bit more though, like below, and put this componentDidMount method in your MyApp.jsx and not directly at the very top level.

<Provider store={store}>
    <BrowserRouter>
        <MyApp/>
    </BrowserRouter>
</Provider>

(Or use NativeRouter instead of BrowserRouter if you're doing React Native)

Micros
  • 5,966
  • 2
  • 28
  • 34
  • Sticking with the BrowserRouter solution, to get access to the history, one might create a ref on the router and proceed to listen via the componentDidMount or useEffect on the level(s) above the BrowseRouter. This way you don't need to add an extra component layer underneath BrowserRouter. – mcksn Apr 05 '20 at 07:00
-1

works like a magic: ‍♂️‍♂️‍♂️

const history = useHistory();      
    
     useEffect(() => {
            if (history) { // for jest sake ))
                history.listen(() => {
                    store.reset();
                });
            }
     }, []);
Gleb Dolzikov
  • 776
  • 8
  • 13