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

时间:2016-04-01 22:47:09

标签: javascript reactjs

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

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'))

有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

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

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