在React组件中未触发onChange回调 [英] onChange callback not firing in React component
问题描述
除非出于某种原因使用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屋!