Ввод формы с использованием формы Redux не обновляется

Мое поле ввода не обновляется при нажатии клавиши:

import React, { Component, PropTypes } from 'react';

import { Field, reduxForm } from 'redux-form';

class CitySelector extends Component {
  render() {
    const { isFetching, pristine, submitting, handleSubmit } = this.props;

    return (
      <form className="form-horizontal col-xs-offset-1" onSubmit={handleSubmit(this.fetchWeather)}>
        <div className="form-group">
          <div className="col-md-4 col-xs-4">
            <Field name="city"
                   component={city =>
                     <input type="text" className="form-control" {...city.input} placeholder="enter a city for a 5 day forecast"/>
                   }
            />
          </div>
          <div className="col-md-3 col-xs-3">
            <button type="submit" className="btn btn-success">Submit</button>
          </div>
        </div>
      </form>
    );
  }
}

export default reduxForm({
  form: 'cityForm'
})(CitySelector);

Нужно ли мне предоставлять обработчик onChange для ввода текста?

Ответ 1

У меня была такая же проблема, и моя ошибка была очень простой.

Вот что у меня было:

import { combineReducers } from 'redux';
import { reducer as forms } from 'redux-form';

import otherReducer from './otherReducer';

export default combineReducers({ otherReducer, forms });

Обратите внимание, что я импортировал редуктор редукционной формы как forms и передавал его, как и моему методу combReducers (например, я сделал с otherReducer), используя сокращенное значение свойства объекта ES6.

Проблема в том, что клавиша , используемая для передачи редуктора редукционной формы на наш combReducers MUST, называется формой. > , поэтому мы должны изменить его на:

export default combineReducers({ customer, form: forms });

или

import { reducer as form } from 'redux-form';
export default combineReducers({ otherReducer, form });

Надеюсь, это поможет кому-то еще...

Ответ 2

Если вы используете неизменяемые структуры данных, а не:

import { reduxForm } from 'redux-form';

используйте это:

import { reduxForm } from 'redux-form/immutable';

Подробнее см. здесь http://redux-form.com/6.7.0/examples/immutable/

Ответ 3

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

Когда вы определяете безстоящий компонент (или только любую функцию) внутри render(), он воссоздается при каждом рендере. И поскольку этот компонент без гражданства передается в качестве опоры (component) на Field, он заставляет Field отображать после каждого отдыха. Таким образом, ваш вход будет терять фокус всякий раз, когда компонент CitySelector отображается, поэтому никакие нажатия клавиш не будут зафиксированы.

Вы должны извлечь свой компонент без гражданства в отдельное определение:

const myInput = ({ input }) => (
  <input type="text" className="form-control" {...input} placeholder="enter a city for a 5 day forecast" />
);

class CitySelector extends Component {
  render() {
    const { isFetching, pristine, submitting, handleSubmit } = this.props;

    return (
      <form className="form-horizontal col-xs-offset-1" onSubmit={handleSubmit(this.fetchWeather)}>
        <div className="form-group">
          <div className="col-md-4 col-xs-4">
            <Field name="city" component={myInput} />
          </div>
          <div className="col-md-3 col-xs-3">
            <button type="submit" className="btn btn-success">Submit</button>
          </div>
        </div>
      </form>
    );
  }
}

Это также делает ваш код более понятным.

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

Ответ 4

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

Это произошло из-за этого:

Я изменил его с input на что-то еще, и он полностью сломал редукционную форму SILENTLY

const TextInput = ({
    input,                                                 <--- DO NOT CHANGE THIS
    placeholder,
    type,
    meta: { touched, error, warning }
  }) => {
    return (
      <div className="row-md">
          <input
            placeholder={placeholder}
            type={type}
            className="form-text-input primary-border"
            {...input}                                     <--- OR THIS
          />
          {touched && ((error && <span>{error}</span>) || (warning && <span>{warning}</span>))}
      </div>
    )
}

Здесь остальная часть моего ввода, если кто-то хочет его изучить:

<Field
  component={TextInput}
  type="tel"
  name="person_tel"
  placeholder="Mobile Phone Number"
  value={this.props.person_tel}
  onChange={(value) => this.props.updateField({ prop: 'person_tel', value })}
/>

Ответ 5

Я узнал/моя проблема была моей

form: formReducer

не был в rootReducer.

formReducer должен быть сверху. Мое дело:

const rootReducer = combineReducers({
   general: generalReducer,
   data: combineReducers({
       user:userReducer,
       todoReducer
   }),
       form: formReducer
   });