我有一个React Component,它封装了<input type='text' />
,但仅在值更改为有效值时调用onChange
。(它自己的状态允许它更改输入的文本值,但当它调用onChange
时,它实际上返回了一个输入解析值的对象。)
export default class MyInputClass extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = { textValue: '' };
// ...
}
// ...
handleChange(e) {
// set the state regardless of value so the input's text changes
this.setState({ textValue: e.target.value});
// determine whether the value is valid, and if so, call onChange()
let myObj = MyParsedObject.parse(e.target.value);
if (myObj !== null && this.props.onChange) {
this.props.onChange(myObj);
}
}
render() {
return <input onChange={this.handleChange} value={this.state.textValue} />;
}
}
// ...
MyInputClass.propTypes = {
onChange: React.PropTypes.func
};
现在我有一个属性onChange
,它是一个React.PropTypes.func
,当输入的更改被触发时,我尝试解析输入的值。如果成功,我会检查this.props.onChange
是否不是null
,然后调用onChange(myParsedObject)
。
这是有效的,但感觉不对。onChange
的处理程序应该期望一个Event参数(或React中的SyntheticEvent),而不是一个对象。此外,这种模式只允许onChange
使用一个处理程序,而实际事件可以有多个处理程序。
您应该如何设计React Components来发射真实事件?
如果MyInputClass
被设计成围绕输入的通用包装器,那么用事件而不是解析的输入来调用this.props.onChange
,并让父组件决定如何解析它可能是有意义的。但是,如果MyInputClass
是特定于的类型输入的包装器,则也传递解析的值可能是有道理的。您可以同时做这两件事,并使其成为API的显式部分:
this.props.onChange(e, myObj);
或者使用onChange
作为通用处理程序,onWhateverChange
作为解析版本;例如,对于JsonInput
组件,可以执行
this.props.onChange(e);
this.props.onJsonChange(parsedJson);