使用 Redux Form 的表单输入不更新

Form input using Redux Form not updating

我的输入字段没有在按键时更新:

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 处理程序吗?

如果您向 Field 提供自定义输入组件,那么是的,您必须调用 input 属性中传递给您的组件的 onChange。事实上,通过传播 city.input,您几乎做到了,但有一个问题。

当您在 inside 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>
    );
  }
}

它还使您的代码更易读。

您可以在 official docs of Redux Form. Note that you could probably use the default input without creating your own, take a look at simple form example 中找到有关该问题的更多信息。

我遇到了同样的问题,我的错误很简单。

这是我得到的:

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

import otherReducer from './otherReducer';

export default combineReducers({ otherReducer, forms });

请注意,我将 redux-form reducer 作为 forms 导入,并使用 ES6 对象 属性 值 shorthand.

问题是 key 用于将 redux-form reducer 传递给我们的 combineReducers MUST被命名为form,所以我们要把它改成:

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

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

希望这对其他人有帮助...

如果您使用的是不可变数据结构,而不是:

import { reduxForm } from 'redux-form';

使用这个:

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

查看此处了解更多信息http://redux-form.com/6.7.0/examples/immutable/

我刚刚遇到了与此问题类似的问题,除了我的表单没有提交而且我的验证函数也没有触发。

原因是:

I changed it from input to something else and it totally broke redux-form 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 })}
/>

我发现/我的问题是我的

form: formReducer

不在 rootReducer 中。

formReducer 必须在最上面。我的情况:

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