React - 当浏览器历史记录发生变化时改变组件状态

6

我有一个React组件,当状态发生改变时会将歌曲ID推送到URL。我的问题是:当用户在浏览器上点击“后退”按钮时,我需要更改SongApp组件的状态。我该如何做?

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
  }
});
1个回答

7

我发现你可以将组件的方法附加到监听器上:

  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);
    }
  }

1
只是想补充一下,看起来你不需要显式地传递“event”,因为它会被传递下去。执行 this.setSongFromHistory(event) 会抛出一个错误。 - Jeff L
2
所示代码会给我一个错误,因为this没有正确设置。解决方法是执行window.addEventListener("popstate",(e) => this.setSongFromHistory(e)) - Garr Godfrey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接