Переопределение поведения onChange с помощью React / Redux Forms

Я создаю сложную форму в React и пытаюсь использовать Redux Forms в качестве вспомогательного инструмента.

Требования к проекту таковы:

  1. На странице будут значения, которые меняются в зависимости от полей ввода (например, в таблице Excel).

  2. Будет как минимум одно поле, которое функционирует как поле ввода и как зависимое поле (его можно изменить, но оно также изменяется при изменении других полей).

  3. Я хочу контролировать, когда меняется состояние. По умолчанию это происходит мгновенно при изменении входных данных, но я бы предпочел иметь задержку вроде этот пример.

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

Мой код размещен на GitHub (побочный вопрос, есть ли у кого-нибудь понимание, почему мой Сайт на страницах GitHub выдает ошибку 404?


person Peter Breen    schedule 22.10.2018    source источник


Ответы (1)


Вам нужно будет создать специальный компонент, который будет помещен внутри Field формы redux-form, в котором вы храните внутреннее состояние, и синхронизировать его с formReducer, когда захотите.

Вы можете добиться этого за пару шагов:

  1. Создайте пользовательский компонент для использования внутри Field. В этот компонент вводится с meta и input prop .

  2. Создайте свой state для своего компонента React, в котором вы будете отслеживать данные, которые вы в конечном итоге отправите в formReducer.

  3. В конструкторе используйте props.input.value, чтобы установить начальное состояние. Если вы сделаете это, вы можете использовать объект initialValues ​​для своего reduxForm.

  4. Используйте connect от react-redux, чтобы можно было использовать создателей действий react-form. В вашем случае вы будете использовать change action creator < / а>.

  5. Создайте свою функцию рендеринга с вашим полем ввода и активируйте действие change, чтобы изменить значение вашего formReducer для этого поля.

Это сводится примерно к следующему:

<Field
  name="daysPerWeek"
  component={MyCustomComponent} // 1
/>

...

class MyCustomComponent {
  constructor(props) {
    super(props);

    this.state = {
      value: props.input.value, // 2 and 3
    }
  }

  ....
}

4:

import { connect } from 'react-redux';
import { change } from 'react-form';

const mapDispatchToProps = (dispatch, ownProps) => ({
  ourCustomChange: (value) => dispatch(change(ownProps.meta.form, ownProps.input.name, value))
})

export default connect(undefined, mapDispatchToProps)(MyCustomComponent);

5:

....
 componentDidUpdate(prevProps, prevState) {
   if (prevState.value !== this.state.value) {
     this.debounceAndEmit();
   }
 }

 debounceAndEmit() {
   // Debounce for some time. Maybe use:
   // import { debounce } from 'throttle-debounce';
   // for that:
   debounce(2000, () => {
     this.props.ourCustomChange(this.state.value)
   })
 }

 handleChange(event) {
   // Do things here like trimming the string, regex, whatever.
   this.setState({ value: event.target.value })
 }

  render() {
    return (
      <input
        {...this.props.input} // Includes standard redux-form bindings for input fields. 
        value={this.state.value}
        onChange={this.handleChange.bind(this)}
      />
    )
  }
....

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

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

Отвечает ли это на ваш вопрос?

person Alserda    schedule 22.10.2018
comment
Большое спасибо, Альсерда, я начну пробовать это и расскажу, как это происходит. - person Peter Breen; 23.10.2018
comment
Все эти советы были верны. Я не совсем закончил с реализацией функциональности, но у меня уже есть много необходимой инфраструктуры. Спасибо! - person Peter Breen; 24.10.2018
comment
@PeterBreen Приятно слышать! Если у вас все еще есть вопросы по этому поводу - я все равно буду активен. - person Alserda; 24.10.2018