Как я могу обновить значения в состоянии из одной функции, а не для каждого значения, имеющего свой собственный прослушиватель событий? - PullRequest
0 голосов
/ 23 апреля 2020

Справочная информация, в настоящее время я работаю над приложением Food Truck Finder, основанным на React. В реакции, насколько я понимаю, если вы хотите изменить значение в состоянии, вы должны иметь прослушиватель, такой как:

handleTruckTypeChange = (idx) => (e) => {
    const newTrucks = this.state.data.map((truck, sidx) => {
      if (idx !== sidx) return truck;
      return { ...truck, type: e.target.value };
    });

    this.setState({ data: newTrucks });
  }

, который отлично работает для некоторых других моих значений в таблице, но у меня есть большой объект для моего объекта расписания. Он обрабатывает десятки значений, и я не хочу писать специальный слушатель событий для каждого из них. Кроме того, у меня есть массив этих объектов расписания, использующих в качестве индекса idx. например, каждый день имеет значения startTime, endTime, openClosed и cost.

Есть ли способ, которым они могут быть обработаны одним и тем же слушателем событий, поэтому я не делаю 7 копий одной и той же функции для обработки каждого изменения?

пример того, как я вызов onChange.

<td>
 <FormControl className={classes.margin}>
  <InputLabel htmlFor="openClosed">O/C</InputLabel>
  <NativeSelect
    id="openClosed"
    value={this.state.schedule[idx].monOpen}
    onChange={this.handleScheduleChange(idx)}
    input={<BootstrapInput />}
  >
   <option aria-label="None" value="" />
   <option value={"0"}>Open</option>
   <option value={"1"}>Closed</option>
  </NativeSelect>
 </FormControl>
</td>

Ответы [ 2 ]

0 голосов
/ 24 апреля 2020

Я понял это своим маленьким путем с помощью Йолла. вот как я это сделал.

handleScheduleChange = (idx) => (e) => {
    const target = e.target;
    const value = target.value;
    const name = target.name;

    this.setState({
      schedule: this.state.schedule.map((item, itemIndex) => {
        if (itemIndex === idx) {
          return {
            ...item,
            [name]: value
          }
        }
        return item;
      })
    });
   console.log(this.state.schedule[idx]);
  };
<td>
                                    <FormControl className={classes.margin}>
                                      <InputLabel htmlFor="openClosed">O/C</InputLabel>
                                      <NativeSelect
                                        id="openClosed"
                                        name="monOpen"
                                        value={this.state.schedule[idx].monOpen}
                                        onChange={this.handleScheduleChange(idx)}
                                        input={<BootstrapInput />}
                                      >
                                        <option aria-label="None" value="" />
                                        <option value={"0"}>Open</option>
                                        <option value={"1"}>Closed</option>
                                      </NativeSelect>
                                    </FormControl>
</td>

важно то, что вы присваиваете каждому компоненту значение имени, которое совпадает со значением в состоянии, которое вы хотите изменить, также передаете индекс массива так, Вы обновляете правильный. Это работает согласованно, поэтому вы можете передать его нескольким функциям, если они все обращаются к одному и тому же массиву в состоянии, для этого примера у меня есть this.state.schedule

0 голосов
/ 23 апреля 2020

Вы можете создать функцию handleOnChange

handleOnChange = field => event => {
    this.setState({[field]: event.target.value})
  }

, и теперь вы можете вызывать эту функцию всякий раз, когда вам нужно обновить состояние с состоянием, которое вы хотите изменить в качестве параметра.

Для вашего сценарий

<td>
 <FormControl className={classes.margin}>
  <InputLabel htmlFor="openClosed">O/C</InputLabel>
  <NativeSelect
    id="openClosed"
    value={this.state.schedule[idx].monOpen}
    onChange={this.handleOnChange('schedule[idx].monOpen')}
    input={<BootstrapInput />}
  >
   <option aria-label="None" value="" />
   <option value={"0"}>Open</option>
   <option value={"1"}>Closed</option>
  </NativeSelect>
 </FormControl>
</td>
...