Как обрабатывать несколько блоков типа «реагируй-выбирай» в реакции - PullRequest
0 голосов
/ 30 марта 2020

Я пишу компонент реагирования с двумя полями реагирования-выбора, когда оба поля имеют значение, которое мне нужно, чтобы передать объединенный объект родителю в качестве обратного вызова. Один из известных мне способов - хранить оба параметра в onchange в состоянии, объединять их и отправлять. Однако, поскольку должны быть показатели производительности, я пытаюсь свести к минимуму повторное рендеринг с использованием изменений состояния.

Вот псевдокод того, что у меня есть сейчас. Метод onchange в обоих случаях устанавливает состояние, но я не хочу, чтобы рендеринг происходил.

fieldSelectorChange = option => {
    this.setState(
      {
        option,
      },
    );
  };


<Select
      options={ fields }
      value={ sortedField }
      searchable
      placeholder={ trans( 'Find an option' ) }
      onChange={ this.fieldSelectorChange }
      autoFocus
    />
    <Select
      options={ sortOptions }
      value={ sortedOrder }
      defaultValue={ sortOptions[ 0 ] }
      placeholder={ trans( 'Choose' ) }
      onChange={ this.fieldSelectorChange }
    />

1 Ответ

1 голос
/ 30 марта 2020

Без кнопки

onSelect1Change(e) {
  this.setState({ select1value: e.target.value });
  if (this.state.select2value) {
    this.props.parentCallback({
      value1: e.target.value,
      value2: this.state.select2value
    })
  }
}

onSelect2Change(e) {
  this.setState({ select2value: e.target.value });
  if (this.state.select2value) {
    this.props.parentCallback({
      value1: this.state.select1value,
      value2: e.target.value,
    })
  }
}

/* ... */
<Select value={this.state.select1value} onChange={onSelect1Change} /* ... */ />
<Select value={this.state.select2value} onChange={onSelect2Change} /* ... */ />

Без кнопки и только один onChange

One onSelectChange, как вы и просили, но в этом случае вы воссоздаете функции стрелок при каждом рендеринге, и он не оптимизирован .

onSelectChange(field, value) {
  this.setState({ [field]: value });

  if (this.state.select1value && this.state.select2value) {
    this.props.parentCallback({
      value1: value,
      value2: this.state.select2value
    })
  }
}

/* ... */
<Select
  value={this.state.select1value}
  onChange={e => this.onSelectChange('select1value', e.target.value)}
  /* ... */
/>
<Select
  value={this.state.select1value}
  onChange={e => this.onSelectChange('select2value', e.target.value)}
  /* ... */
/>

Если вы хотите избежать этого, вам нужно создать еще две функции и использовать их внутри ваших компонентов

onSelect1Change = e => this.onSelectChange('select1value', e.target.value)
onSelect2Change = e => this.onSelectChange('select2value', e.target.value)

Вы также можете добавить некоторую проверку здесь, если хотите :

if (field in this.state) {
  this.setState({ [field]: value });
} else {
  // field is missing, do something with this case
}

Форма и сумма

Это обычное дело - оборачивать поля ввода в компонент формы.

onSelect1Change(e) {
  this.setState({ select1value: e.target.value });
}

onSelect2Change(e) {
  this.setState({ select2value: e.target.value });
}

onSumbit(e) {
  e.preventDefault();
  /* get both values from state and do something */
  console.log(this.state.select1value, this.state.select2value);
}
/* ... */
<form onSubmit={onSubmit}>
  <Select value={this.state.select1value} onChange={onSelect1Change} /* ... */ />
  <Select value={this.state.select2value} onChange={onSelect2Change} /* ... */ />
  <input type="submit" value="Submit" />
</form>

Кнопка

Но вы может сделать это и без формы. Вы можете просто сделать кнопку и получить значения из состояния по клику пользователя.

onSelect1Change(e) {
  this.setState({ select1value: e.target.value });
}

onSelect2Change(e) {
  this.setState({ select2value: e.target.value });
}

onClick(e) {
  e.preventDefault();
  /* get both values from state and do something */
  console.log(this.state.select1value, this.state.select2value);
}
/* ... */
<div>
  <Select value={this.state.select1value} onChange={onSelect1Change} /* ... */ />
  <Select value={this.state.select2value} onChange={onSelect2Change} /* ... */ />
  <button onClick={onClick}>Click me!</button>
</div>
...