Reputation: 14318
I have a React Component that wraps an <input type='text' />
but only calls onChange
when the value has changed to something valid. (Its own state allows it to change the text value of the input, but when it calls onChange
, it actually returns an object of the parsed value of the input.)
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
};
Right now I have a property onChange
, which is a React.PropTypes.func
, and when the input's change is triggered, I attempt to parse the input's value. If it's successful, I check to see if this.props.onChange
is not null
, and then call onChange(myParsedObject)
.
This works, but it doesn't feel right. Handlers of onChange
should expect an Event parameter (or SyntheticEvent in React), not an object. Further, this pattern only allows one handler for onChange
, whereas real Events can have multiple handlers.
How are you supposed to design React Components to emit real events?
Upvotes: 2
Views: 2462
Reputation: 159105
If MyInputClass
is designed to be a generic wrapper around inputs, it might make sense to call this.props.onChange
with the event, rather than the parsed input, and let the parent component decide how to parse it. If, however, MyInputClass
is a wrapper for a specific type of input, it might make sense to also pass on the parsed value. You could always do both, and make it an explicit part of the API:
this.props.onChange(e, myObj);
Or use onChange
as the generic handler and onWhateverChange
as the parsed version; for example, for a JsonInput
component, you might do
this.props.onChange(e);
this.props.onJsonChange(parsedJson);
Upvotes: 1