通知全局事件组件的最佳方式

Best way to notify a component of a global event

本文关键字:最佳 方式 组件 全局 事件 通知      更新时间:2023-12-01

我有一个数据网格组件,用户可以在其中选择多行。组件管理当前选择的行作为其状态的一部分:

var Datagrid = React.createClass({
  getInitialState() {
    return {
      selection: []
    }
  },
  handleRowClick(id, event) {
    if (event.ctrlKey) {
      this.setState({ selection.concat([id]) });
    }
  },
  render() {
    return
      <div>
        {this.props.data.map( rowdata => <Row data={rowdata}> )}
      </div>
    ;
  }
});
ReactDOM.render(<Datagrid data={data}>, document.querySelector('#grid1'))

这很好地工作并封装了(实际上相当复杂的)选择逻辑。

但现在我希望这个组件在单击页面正文时取消选择所有行。

让全局存储管理所有数据网格的选择似乎相当麻烦,只是为了能够取消选择它们。我喜欢选择逻辑封装在组件中的事实,我只想通知它全局事件。

我曾想过将回调作为重置自身的道具来传递,但这似乎非常复杂:

var notification = false;
body.onclick = function () {
  notification = function() { notification = false; } // Marks a pending notification
  ReactDOM.render(<Datagrid data={data} notification={notification}>, document.querySelector('#grid1'))
}
var Datagrid = React.createClass({
  ...
  render() {
    if (this.props.notification) {
      this.setState({ selection: [] });
      this.props.notification(); // Reset the notification
    }
    ...
  }
});
ReactDOM.render(<Datagrid data={data} notification={notification}>, document.querySelector('#grid1'))

有更好的方法吗?

我认为处理这种情况的正确方法是在组件安装时设置侦听器,然后在组件卸载时将其删除,如下所示:

var Datagrid = React.createClass({
  getInitialState() {
    return {
      selection: []
    }
  },
  componentDidMount() {
    document.body.addEventListener('click', this.handleClear);
  },
  componentWillUnmount() {
    document.body.removeEventListener('click', this.handleClear);
  },
  handleClear() {
    this.setState({ selection: []});
  },
  handleRowClick(id, event) {
    if (event.ctrlKey) {
      this.setState({ selection.concat([id]) });
    }
  },
  render() {
    return
      <div>
        {this.props.data.map( rowdata => <Row data={rowdata}> )}
      </div>
    ;
  }
});