让React组件像DOM组件那样触发更改事件

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

本文关键字:组件 事件 React DOM      更新时间:2023-09-26

我有一个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);