在React组件中未触发onChange回调 [英] onChange callback not firing in React component

查看:124
本文介绍了在React组件中未触发onChange回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

除非出于某种原因使用jQuery,否则我的onChange()函数不会运行.我必须在componentDidMount()中添加onChange侦听器的原因是因为我使用的是MaterializeCSS,它将您的select标记转换为ul.下面的代码可以正常工作:

My onChange() function does not run unless I use jQuery for some reason. The reason why I have to add the onChange listener in componentDidMount() is because I'm using MaterializeCSS which transforms your select tag into a ul. The code below works fine:

onChange(e) {
  let inspectionTime = e.target.value;
  this.setState({ inspectionTime });
}

componentDidMount() {
  let $inspectionDropdown = $(ReactDOM.findDOMNode(this.refs.inspection));
  $inspectionDropdown.on('change', this.onChange);
}

但此代码不:

onChange(e) {
  let inspectionTime = e.target.value;
  this.setState({ inspectionTime });
}

componentDidMount() {
  let inspectionDropdown = ReactDOM.findDOMNode(this.refs.inspection);
  inspectionDropdown.addEventListener('change', this.onChange);
}

如果有帮助,这里是整个组件的代码:

Here is the code for the whole component if it helps at all:

import React from 'react';
import ReactDOM from 'react-dom';

class InspectionMode extends React.Component {
  constructor(props) {
    super(props);
    this.onChange = this.onChange.bind(this);
    this.defaultValue = 'selected';
    this.state = { inspectionTime: 0 };
  }

  onChange(e) {
    let inspectionTime = e.target.value;
    this.setState({ inspectionTime });
  }

  componentDidMount() {
    let inspectionDropdown = ReactDOM.findDOMNode(this.refs.inspection);
    inspectionDropdown.addEventListener('change', this.onChange);
  }

  render() {
    let classes = 'input-field col s10 offset-s1 l3';

    return (
      <div className={classes}>
        <select onChange={this.onChange} ref="inspection" value={this.state.inspectionTime}>
          <option value="0">None</option>
          <option value='5'>5 Seconds</option>
          <option value='10'>10 Seconds</option>
          <option value='15'>15 Seconds</option>
        </select>
        <label>Inspection Time</label>
      </div>
    );
  }
}

export default InspectionMode;

推荐答案

问题是插件正在发出自定义更改事件. React的事件系统无法识别自定义事件(不确定原因).

The problem is that the plugin is emitting a custom change event. React's event system doesn't recognize custom events (not sure why).

在这种情况下,手动更改侦听器是正确的解决方案.改善此问题的方法是将select元素抽象为"atom".

In this case a manual change listener is the right solution. The way you improve this is by abstracting the select element to an 'atom'.

class Select extends React.Component {
  static propTypes = {
    value: React.PropTypes.string,
    options: React.PropTypes.arrayOf(
      React.PropTypes.shape({
        text: React.PropTypes.string.isRequired,
        value: React.PropTypes.string.isRequired,
      })
    ).isRequired
  };
  constructor() {
    super();
    this.onChange = this.onChange.bind(this);
  }

  onChange(e) {
    this.props.onChange(e.target.value);
  }

  componentDidMount() {
    let select = this.refs.select;
    select.addEventListener('change', this.onChange, false);
  }

  componentWillUnmount(){
    let select = this.refs.select;
    select.removeEventListener('change', this.onChange, false);  
  }

  render() {
    let classes = 'input-field col s10 offset-s1 l3';

    return (
      <div className={classes}>
        <select ref="select" value={this.props.value}>
          {this.props.options.map((x) => {
            return <option key={x.value} value={x.value}>{x.text}</option>;
          })}
        </select>
      </div>
    );
  }
}

然后您可以在InspectionMode或用户界面的其他任何地方使用它.

You can then use this in InspectionMode or anywhere else in your UI.

class InspectionMode extends React.Component {
  constructor(props) {
    super(props);
    this.onChange = this.onChange.bind(this);
    this.value = 'selected';
    this.state = { inspectionTime: 0 };
  }

  onChange(inspectionTime) {
    this.setState({ inspectionTime });
  }

  render() {
    return (
      <div>
        <Select 
          value={this.state.inspectionTime}
          onChange={this.onChange}
          options={[
            {value: '0', text: 'None'},
            {value: '5', text: '5 seconds'},
            {value: '10', text: '10 seconds'},
            {value: '15', text: '15 seconds'},
          ]}
        />
        <label>Inspection Time</label>
      </div>
    );
  }
}

这篇关于在React组件中未触发onChange回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆