【问题标题】:Form input using Redux Form not updating使用 Redux Form 的表单输入未更新
【发布时间】:2017-02-15 17:21:56
【问题描述】:

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

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

【问题讨论】:

    标签: reactjs redux redux-form


    【解决方案1】:

    如果您向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>
        );
      }
    }
    

    它还使您的代码更清晰。

    您可以在 Redux Form 的 official docs 中找到有关该问题的更多信息。请注意,您可以使用默认的input 而无需创建自己的,请查看simple form example

    【讨论】:

    • 我的 reducer 是否需要更新一个名为 city 的属性?
    • 嗯,不,Redux Form 自己管理状态更新。我真的无法在这里找到您的问题的根源。您能在控制台中看到任何错误吗?
    • 控制台中没有错误,我可以看到这个动作被记录下来:action Object {type: "redux-form/CHANGE", meta: Object, payload: "a"}
    • 我没想到我需要处理 redux-form/CHANGE
    • 如果我重复输入 a ,我只会得到相同的操作,有效负载中只有 1 个字母,这表明商店没有正确更新
    【解决方案2】:

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

    这是我所拥有的:

    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 Object 属性值简写将它按原样传递给我的 combineReducers(就像我对 otherReducer 所做的那样)。

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

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

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

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

    【讨论】:

    • 很好地抓住了关键位
    • 文档需要这些信息。执行“入门”指南会将您带入陷阱。这是修复。
    • 我真的忘记了这个 'import { reducer as forms } from 'redux-form';
    【解决方案3】:

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

    import { reduxForm } from 'redux-form';

    使用这个:

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

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

    【讨论】:

    • 谢谢,我浪费了几个小时想知道为什么我的输入没有更新!
    • 谢谢,这就是我的问题所在。如果你碰巧使用react-boilerplate,你就会遇到这个问题。
    【解决方案4】:

    我只是遇到了与这个问题类似的问题,除了我的表单没有提交并且我的验证功能也没有触发。

    这是因为:

    我把它从 input 改成了别的东西,它完全破坏了 redux-form 静默

    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
         });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-10
        • 1970-01-01
        • 1970-01-01
        • 2016-04-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多