Search code examples
reactjshtml5-history

React—Change a components state on window.history.popstate


I have a React component that pushes song IDs to the url when the state changes. My problem is that when a user clicks 'back' on their browser, I need to change the state of my SongApp component. How do I do this?

class SongApp extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      song: props.songId
    }

    this.setSong = this.setSong.bind(this);
  }

  setSong(e) {
    var songId = e.target.id;
    this.setState({song: songId})
    window.history.pushState({song: songId}, '', '?s='+songId)
  }

  render() {
    var id = this.state.song;

    var content = id ? <SongDisplay lyrics={ this.props.songData[id].lyrics } /> : <SongIndex songData={this.props.songData} setSong={this.setSong}/>
    return(
      <div className="song-app">
        {content}
      </div>
    )
  }
}

window.addEventListener('popstate', function(event) {
  console.log('popstate fired!');
  debugger;
  if(event.state.song) {
    // change SongApp state
  }
});

Solution

  • I found out you can attach the component's method to a listener:

      componentDidMount() {
        window.addEventListener("popstate", this.setSongFromHistory);
      }
    
      setSongFromHistory(e) {
        if(e.state.song){
          e.preventDefault(); // stop request to server for new html
          e.stopPropagation();
          this.setState({song: e.state.song});
          $('html,body').scrollTop(0);
        }
      }