【问题标题】:React Redux - Why can't I easily set initialValues from this.props?React Redux - 为什么我不能从 this.props 轻松设置 initialValues?
【发布时间】:2017-11-24 11:08:37
【问题描述】:

所以我继承了一个项目,我需要在其中使用FieldArrays 来创建一个动态的项目列表。它所在的“表单”实际上不在<form> 中,因此我不得不将我的FieldArrays 代码分割成自己的组件,以便让redux 神奇地让它“工作”来做我想做的事情希望它做,例如用数据预填充字段,能够轻松添加/删除字段等。

问题是我似乎无法使用来自更高组件的道具预先填充组件,以便 redux FieldArray 可以将其拾取,无论我尝试了什么。

这是我的代码:

renderFlooring({ fields, meta: { touched, error, submitFailed } }) {

      return (
        <div>
          <div>
            <div className={styles.flooringHeading}>
              <h3> Site Specifications </h3>
              <button type="button" className={styles.add} onClick={() => fields.push({})}>Add Square Footage</button>
            </div>
            {(touched || submitFailed) && error && <span>{error}</span>}
            {fields.length === 0 &&
              <p className={styles.noFlooring}>No square footage or flooring type has been added.</p>
            }
          </div>
          <ul className={styles.sqFtList}>
            {fields.map((flooring, index) =>
              <li className={styles.card} key={index}>
                <div className="page-form__block">
                  <p> Estimate the total area of work in square feet </p>
                  <Field name={`${flooring}.square_footage`} onChange={this.changeFlooringSquareFootage} component={TextField} hintText="Square Feet" />
                </div>
                <div className="page-form__block">
                  <p> Enter Floor Type </p>
                  <Field name={`${flooring}.flooring_type`} onChange={this.changeFlooringType} component={TextField} hintText="Floor Type (VCT, Carpet, Vinyle)" />
                </div>
                <button
                  type="button"
                  title="Remove"
                  className={styles.remove}
                  onClick={() => {
                    fields.remove(index);
                    this.props.removeFlooring(index);
                  }}>Remove</button>
              </li>
            )}
          </ul>
        </div>
      );
    }



  render() {
    return (
      <FieldArray name="flooring" component={this.renderFlooring}/>
    );
  }
}

export default reduxForm({
  form: 'manageSquareFootageForm',
  initialValues: this.props.flooring
})(ManageSquareFootageForm);

导入此特定组件的组件如下所示:

<ManageSquareFootageForm
   changeFlooringType={this.changeFlooringType}
   changeFlooringSquareFootage={this.changeFlooringSquareFootage}
   removeFlooring={this.removeFlooring}
   flooring={this.props.flooring}
/>

我什至尝试在我的&lt;ManageSquareFootageForm&gt; 上添加initialValues,但这最终导致我的fields.push({}) 功能停止工作。

我的数据如下所示:

[
   {square_footage: "500", flooring_type: "carpet"},
   {square_footage: "1000", flooring_type: "carpet"}
]

有什么我可以直接做的吗?

提前致谢!

【问题讨论】:

    标签: reactjs redux redux-form


    【解决方案1】:

    这是因为reduxFrom HOC 不知道组件道具,你确实设置了initialValues from prop 之类的

    const FootableForm = reduxForm({
      form: 'manageSquareFootageForm'
    })(ManageSquareFootageForm);
    
    export default connect((state, props) => ({
        initialValues: props.flooring 
      }))(FootableForm)
    

    但是,您的字段不会在初始加载时生成,因此不会被填充,您宁愿使用 ReduxForm 中的 change 函数更新值。

    const defaultValues = { square_footage: "500", flooring_type: "carpet" }
    
    
    class FieldArraysForm extends React.Component {
      componentDidUpdate(prevProps) {
        const {flooring, change} = this.props;
        const {flooring: prevflooring} = prevProps;
        console.log(JSON.stringify(flooring));
        // Do nothing if no flooring, or no change to flooring
        if (!flooring || flooring === prevflooring) {
          return;
        }
    
        if (!prevflooring || flooring.length > prevflooring.length) {
          change('flooring', flooring.slice(0, flooring.length - 1).concat(defaultValues));
        }
    
      }
      render() {
        const { handleSubmit, pristine, reset, submitting } = this.props;
        return (
          <form onSubmit={handleSubmit}>
            <FieldArray name="flooring" component={renderFlooring} />
          </form>
        );
      }
    };
    
    
    const FieldForm = reduxForm({
      form: 'fieldArrays', // a unique identifier for this form
      validate,
    })(FieldArraysForm);
    
    export default connect(state => ({
      flooring: (getFormValues('fieldArrays')(state) || {}).flooring
    }))(FieldForm);
    

    检查工作codeSandbox

    【讨论】:

    • 您好,感谢您的回答,但是在尝试了这段代码之后,它仍然没有填充我的 FieldArray 中的字段。该代码实际上是有道理的,而且我还更新了我的问题以显示数据的样子。它与字段的名称相匹配,因此它应该知道抓取它。我这里还有什么遗漏的吗?
    • name={`${flooring}.square_footage`} 应该做什么
    • 据我了解,这会让字段知道它是传递下来的地板对象的子元素,对吧?
    • 我尝试将它们更改为name="square_footage",但它仍然没有这样做:/
    • 你可以试试,fields.getAll().map,而不是普通的fields.map。不确定它是否会起作用
    猜你喜欢
    • 2016-09-10
    • 2020-08-31
    • 2013-04-03
    • 1970-01-01
    • 2017-11-29
    • 2020-03-31
    • 2017-08-18
    • 2017-12-18
    • 2017-12-08
    相关资源
    最近更新 更多