简体   繁体   中英

Have React component trigger a change event the way DOM components would

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?

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM