0

I'm trying to run a function every time the url is changed. Basically I have a navbar which contains a search form. When the user searches it will update the url to reflect the data entered by the user:

this.props.history.push(`/searchusers?q=${this.state.searchBarData}`)

This will push the user to the /searchusers page

On the /searchusers page I would like to add a listener to check when the url of the page is updated (i.e. if the user enters more data into the search bar). I am using the following code on th /searchusers page to initialize the listener:

componentDidMount(){
    window.addEventListener('hashchange', console.log("changed"), false)
}

The function runs when the component loads initially, but does not work when the url is changed after that. Any ideas where I might be going wrong? Thanks!

Djaenike
  • 1,645
  • 5
  • 21
  • 32
  • 2
    can you specify how you change the url?? – Jatin Parmar Oct 19 '19 at 13:06
  • 1
    You should give more detail about how your URL changes, but be careful because your event handler is undefined, since you are calling the console.log function right away and not setting it as a callback – giuseppedeponte Oct 19 '19 at 13:07
  • 2
    Try this instead `window.addEventListener('hashchange', function () { console.log("changed") }, false)` – giuseppedeponte Oct 19 '19 at 13:08
  • I have a search bar which will change the URL when the user enters some data. Since the page doesn't refresh every time the user enters the data, I'd like to be able to somehow execute a function every time that happens. Just to test it out, I am trying to `console.log` something eveytime it is updated – Djaenike Oct 19 '19 at 13:50
  • @giuseppedeponte unfortunately could not get that to work. Now it won't even `console.logg` when the page load initially. – Djaenike Oct 19 '19 at 13:52
  • I added a little more detail as to what I'm trying to accomplish. Hope it helps! – Djaenike Oct 19 '19 at 14:01
  • 1
    I thought the `hashchange` event only listened for changes in the hash part of the url which is what comes after the `#` to listen to changes on the url when using react router I believe there's a different event and you can only do that in React and not on the window. Not sure what to do when using the history package though – apokryfos Oct 19 '19 at 14:36

1 Answers1

2

As giuseppedeponte said, the main obvious problem is this:

componentDidMount(){
    window.addEventListener('hashchange', console.log("changed"), false)
}

when the component mounts console.log('changed') is called and the handler is undefined (return value of console log).

Replace by:

componentDidMount(){
    window.addEventListener(
        'hashchange',
        function () {
            console.log("changed")
        },
        false
    );

}

And the console log will be called each time the hash change.

That lead us to the second problem:

this.props.history.push(`/searchusers?q=${this.state.searchBarData}`)

This is not actually changing the hash of the url but the query string and according to msdn won't trigger an hashchange event.

This stackoverflow question might help you to track history change via history.push

remix23
  • 2,632
  • 2
  • 11
  • 21
  • Thank you, looks like I should be using `window.popstate = (console.log)`. Should this go into the `componentDidMount()` part, or should I stikc into `componentDidUpate()`? My fear is that with `componentDidUpdate` it will trigger an infinite loop – Djaenike Oct 19 '19 at 15:42
  • 1
    Use addEventListner in componentDidMount as it's called when the component mounts, use removeEventListner in componentWillUnmount. componentDidUpdate wouldn't create an infinite loop but would add a new listener after each render of the component. – remix23 Oct 19 '19 at 21:25