React:如何侦听子组件事件

React: How to listen to child component events

本文关键字:组件 事件 何侦听 React      更新时间:2023-09-26

我有一个组件,比方说它包含一个窗体。该窗体有一些子组件,它们本质上是用于输出文本输入和选择菜单的UI小部件。

select菜单组件有点花哨,并使用onChange事件进行一些状态维护。

我的问题是;如何从父(窗体)组件中勾入选择菜单的onChange事件?我不能通过道具传递onChange,因为我已经在select组件中指定了onChange,我不想覆盖它

示例:

var Form = React.createClass({
    handleSelectChange: function(){
        // Do something when <Select /> changes
    },
    render: function () {    
        var selectMenuOptions = [
            {label: 'Choose...', value: ''},
            {label: 'First option', value: 'one'},
            {label: 'Second option', value: 'two'}
        ];
        return (
            <form>
                <Select name="selectMenu" id="selectMenu" options={selectMenuOptions} />
            </form>
          );
        }
});
var Select = React.createClass({
    getDefaultProps: function() {
        return {
          options: [],
          className: "select"
        };
      },
    getInitialState: function () {
        return {
            buttonText: 'Loading...',
            defaultValue: null 
        };
    },
    handleChange: function (e) {
        // Update buttonText state
    },
    render: function () {
        return (
            <div className={this.props.className}>
                <div className="select__button">{this.state.buttonText}</div>
                <select className="select__selector" 
                        ref="select" 
                        onChange={this.handleChange}>
                        {this.props.options.map(function(option, i){
                            return (<Option option={option} key={i} />);
                        })}
                </select>
            </div>
        );
    }
});

使用<Select onChange={...} />不会覆盖Select的render方法中的<select onChange={...} />。它所渲染的<Select/>分量和<select/>分量具有完全不同的props集合。

我认为,最简单的方法是让Select的handleChange方法调用this.props.onChange。您可以将handleChange接收到的e参数传递给它:

var Form = React.createClass({
  handleSelectChange: function(){
    // Do something when <Select /> changes
  },
  render: function () {
    // ...
    return (
      <form>
        <Select name="selectMenu"
          id="selectMenu"
          options={selectMenuOptions}
          onChange={this.handleSelectChange} />
      </form>
      );
    }
});
var Select = React.createClass({
  // ...
  handleChange: function (e) {
    if (this.props.onChange) {
      this.props.onChange(e);
    }
    // Update buttonText state
  },
  render: function () {
    return (
      <div className={this.props.className}>
        <div className="select__button">{this.state.buttonText}</div>
        <select className="select__selector"
          ref="select"
          onChange={this.handleChange}>
          {this.props.options.map(function(option, i){
            return (<Option option={option} key={i} />);
          })}
        </select>
      </div>
    );
  }
});