表单输入使用Redux Form不更新

时间:2016-10-06 20:14:46

标签: reactjs redux redux-form

按键时我的输入字段未更新:

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

5 个答案:

答案 0 :(得分:62)

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

这就是我所拥有的:

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

import otherReducer from './otherReducer';

export default combineReducers({ otherReducer, forms });

请注意,我正在将redux-form reducer导入为forms并将其原样传递给我的combineReducers(就像我使用otherReducer一样),使用ES6 Object属性值缩写。

问题是用于将 redux-form reducer 传递给combineReducers 必须命名为表单,所以我们必须将其更改为:

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

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

希望这有助于其他人...

答案 1 :(得分:24)

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

import { reduxForm } from 'redux-form';

使用它:

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

有关详细信息,请参阅此处http://redux-form.com/6.7.0/examples/immutable/

答案 2 :(得分:1)

如果您向Field提供自定义输入组件,则是,您必须在onChange道具内调用input到您的组件。事实上,你几乎通过传播city.input来做对了,但是有一个问题。

当您在 render()方法中定义无状态组件(或任何函数)时,会在每次渲染时重新创建它。并且因为此无状态组件作为prop(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 Form的official docs中找到有关该问题的更多信息。请注意,您可以在不创建自己的情况下使用默认input,请查看simple form example

答案 3 :(得分:1)

我只是遇到类似这个问题的问题,除了我的表单没有提交,我的验证功能也没有解决。

原因是:

  

我将它从input更改为其他内容并且它完全打破了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 })}
/>

答案 4 :(得分:0)

我发现了/我的问题是我的

form: formReducer

不在rootReducer中。

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

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