如何编写通用方法来处理React中的多个状态更改

问题描述 投票:0回答:2

我正在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;
javascript reactjs methods
2个回答
1
投票

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

0
投票

您可以为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}
/>
© www.soinside.com 2019 - 2024. All rights reserved.