路由更改后停止事件监听

Cys*_*ack 0 reactjs react-router

在我的一个组件中,我监听键盘事件,一些键会触发某些行为。

但是,一旦路由发生变化并且用户导航到另一个组件,我就不再想对键盘事件做出反应。实现这一点的唯一方法是将我的事件侦听器移动到更高阶的组件并根据当前活动路由有条件地对事件做出反应或丢弃事件吗?

这是我的最高阶组件:

class AppRouter extends Router {
  render() {
    return (
      <Router>
        <div>
          <ul>
            <li><Link to="/">Explorer</Link></li>
            <li><Link to="/charts">Charts</Link></li>
          </ul>

          <hr/>

          <Route exact path="/" component={Viewer}/>
          <Route path="/charts" component={Charts}/>
        </div>
      </Router>
    );
  }
}

class App extends Component {
  render() {
    return (
      <div className="App">
        <AppRouter />
      </div>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

和我的事件侦听器,在 Viewer 组件中找到,但我不想在其他任何地方都处于活动状态:

  handleKeyDown(e) {
    if (e.which === 37)
      return this.fetchSibling('next');
    if (e.which === 39)
      return this.fetchSibling('previous');
  }

  componentWillMount() {
    document.addEventListener('keydown', this.handleKeyDown.bind(this));
  }
Run Code Online (Sandbox Code Playgroud)

Cys*_*ack 5

我找到的解决方案包括在卸载组件之前删除事件侦听器。但是,要做到这一点,我需要保留对事件处理程序的引用,它也正确绑定this到它。这是我使用的代码:

componentWillMount() {
    this.setState({listener: this.handleKeyDown.bind(this)}, () => document.addEventListener('keydown', this.state.listener));
  }

  componentWillUnmount() {
    document.removeEventListener('keydown', this.state.listener);
    this.setState({listener: null});
  }
Run Code Online (Sandbox Code Playgroud)

  • 这正是我要建议的。 (2认同)