当我们使用内置HTML输入组件时,onChange
侦听器被赋予SyntheticEvent
的实例,这允许我们执行类似
onChange = (event) => {
this.setState({
[event.target.name]: event.target.value
})
};
render() {
return (
<div>
<input
type="text"
name="username"
value={ this.state.username }
onChange={ this.onChange } />
<input
type="password"
name="password"
value={ this.state.password }
onChange={ this.onChange } />
</div>
);
}
请注意,我可以为多个表单控件使用相同的侦听器。但是,如果我们使用自定义表单控件,比如DatePicker或更像特定于域的UserSelector,这些组件通常都有自己的API来处理更改(例如onChange(newValue)
或onChange(oldValue, newValue)
)。这迫使我为每个字段写一个监听器。
有没有好办法处理这种情况?
答案 0 :(得分:2)
一种方法是构造自己的数据结构以发出类似于事件的信号。
import React, { PureComponent } from 'react';
const onChange = component => event => {
component.props.onChange({
target: {
value: Object.assign({}, component.props.value, {
[event.target.name]: event.target.value,
})
}
})
};
export default class UserControl extends PureComponent {
render () {
return (
<div>
<input name="name" value={this.props.value.name} onChange={onChange(this)} />
<input name="age" value={this.props.value.age} onChange={onChange(this)} />
</div>
);
}
};
您的自定义事件对象可以根据需要选择React合成事件的其他键。
请注意,onChange处理程序不必绑定到类。由于它是通用的,因此可以作为单独的一部分代码存在,该代码首先接受组件。
编辑:要考虑的一件事是在需要时也传递stopPropagation方法。我还没有自己做,但这似乎行得通。注意event.persist()。这样可以确保React不重用SyntheticEvent。
const onChange = component => event => {
event.persist();
component.props.onChange({
stopPropagation: event.stopPropagation.bind(event),
target: {
value: Object.assign({}, component.props.value, {
[event.target.name]: event.target.value
})
}
});
};