我正在React中构建一个运动追踪器应用程序。
现在,我正在构建CreateExercise组件以提交表单,因此我需要更新每个值的状态。为了做到这一点,我创建了处理这些更改的方法(onChangeUsername,onChangeDescription,onChangeDuration等...),但我真的不喜欢重复这样的方法。
如何编写更通用的方法来处理此任务?
class CreateExercise extends Component {
constructor(props) {
super(props);
this.state = {
username: '',
description: '',
duration: 0,
date: new Date(),
users: []
}
}
onChangeUsername = (e) => {
this.setState({
username: e.target.value
});
}
onChangeDescription = (e) => {
this.setState({
description: e.target.value
});
}
onChangeDuration = (e) => {
this.setState({
duration: e.target.value
});
}
onChangeDate = (date) => {
this.setState({
date: date
});
}
onSubmit = (e) => {
e.preventDefault();
const exercise = {
username: this.state.username,
description: this.state.description,
duration: this.state.duration,
date: this.state.date
}
console.log(exercise);
window.location = '/';
}
render() {
return(
<div>
<h3>Create New Exercise Log</h3>
<form onSubmit={ this.onSubmit }>
<div className='form-group'>
<label>Username:</label>
<select
ref='userInput'
required
className='form-control'
value={ this.state.username }
onChange={ this.onChangeUsername }
>
{ this.state.users.map((user) => (
<option key={user} value={user}>{user}</option>
))
}
</select>
</div>
<div className='form-group'>
<label>Description:</label>
<input
type='text'
required
className='form-control'
value={ this.state.description }
onChange={ this.onChangeDescription}
/>
</div>
<div className='form-group'>
<label>Duration:</label>
<input
type='text'
className='form-control'
value={ this.state.duration }
onChange={ this.onChangeDuration }
/>
</div>
<div className='form-group'>
<label>Date:</label>
<div>
<DatePicker
selected={ this.state.date }
onChange={ this.onChangeDate }
/>
</div>
</div>
<div className='form-groupe'>
<input
type='submit'
value='Create Exercise Log'
className='btn btn-primary'
/>
</div>
</form>
</div>
);
}
}
export default CreateExercise;
使用partial application,在组件中创建一个函数,该函数采用字段名称,并返回设置状态的函数:
onChangeValue = field => e => {
this.setState({
[field]: e.target.value
});
};
用法:
onChangeUsername = onChangeValue('username');
onChangeDescription = onChangeValue('description');
onChangeDuration = onChangeValue('duration');
您进一步扩展了想法,以也支持onChangeDate
:
onChangeValue = (field, valueTransformer = e => e.target.value) => e => {
this.setState({
[field]: valueTransformer(e.target.value)
});
};
这不会更改其他on
功能,因为默认是获取e.target.value
。要使用onChangeDate
,我们现在可以更改valueTransformer
:
onChangeDate = onChangeValue('date', v => v);
您可以为name
元素定义HTML
,并使用它来设置值:
onChange = e => {
this.setState({ [e.target.name]: e.target.value });
};
对应的JSX元素:
<input
type="text"
name="description"
required
className="form-control"
value={this.state.description}
onChange={this.onChange}
/>