【问题标题】:React Redux Form: form is submiting with old valuesReact Redux Form:表单正在提交旧值
【发布时间】:2018-03-15 19:38:01
【问题描述】:

我有一个 Redux 表单中的 FieldArray,我将对象推送到这个数组中,然后我有一个回调来触发一个函数来发出 POST 请求。

当我提交表单时,我得到了旧值,因为 Redux 表单的 push() 方法是来自 redux 的异步调度。

// Parent component
<FieldArray
     name="myObjects"
     component={ChildComponent}
     onSubmitObjects={this.onSubmit} />

// Function
onSubmit = async () => {
    const { getFormValues } = this.props;

    const data = {
        myObjects: getFormValues.myObjects
    }

    try {
        // const contact = await Service.updateUser(data);

    } catch (e) {
        console.log(e)
    }
}

我需要在 push 方法之后提交带有添加到数组中的新值的表单。

// Function inside ChildComponent
addNewObject = () => {
        const { fields, onSubmitObjects} = this.props;

        fields.push({
            number: 1,
            name: 'Foo',
        });

        if (onSubmitObjects) {
            onSubmitObjects(); // cb() to trigger a function in the parent component
        }
    }

有没有办法在 push 方法之后使用新值调用回调?

【问题讨论】:

  • codesandbox.io/s/6wxz7437rk 如果你使用 Redux-form 中的 FieldArray,我不认为它们是 onSubmitObjects 的道具。你能澄清问题吗?
  • @FisNaN 我必须创建此回调,因为我没有使用 handleSubmit 道具提交表单。当我点击一个按钮时,我必须推送数组中的对象并使用这个新数组调用 API

标签: javascript reactjs redux redux-form


【解决方案1】:

你应该使用 form 和 redux-form handleSubmit 来包装你的 FieldArray。您可以选择将您的自定义提交函数(发出 API 请求、提交验证等)传递给 handleSubmit,因此它看起来像这样 &lt;form onSubmit={handleSubmit(this.onSubmit)}&gt; ...

redux-form official docs看这个例子:

FieldArraysForm.js

import React from 'react'
import {Field, FieldArray, reduxForm} from 'redux-form'
import validate from './validate'

const renderField = ({input, label, type, meta: {touched, error}}) => (
  <div>
    <label>{label}</label>
    <div>
      <input {...input} type={type} placeholder={label} />
      {touched && error && <span>{error}</span>}
    </div>
  </div>
)

const renderHobbies = ({fields, meta: {error}}) => (
  <ul>
    <li>
      <button type="button" onClick={() => fields.push()}>Add Hobby</button>
    </li>
    {fields.map((hobby, index) => (
      <li key={index}>
        <button
          type="button"
          title="Remove Hobby"
          onClick={() => fields.remove(index)}
        />
        <Field
          name={hobby}
          type="text"
          component={renderField}
          label={`Hobby #${index + 1}`}
        />
      </li>
    ))}
    {error && <li className="error">{error}</li>}
  </ul>
)

const renderMembers = ({fields, meta: {error, submitFailed}}) => (
  <ul>
    <li>
      <button type="button" onClick={() => fields.push({})}>Add Member</button>
      {submitFailed && error && <span>{error}</span>}
    </li>
    {fields.map((member, index) => (
      <li key={index}>
        <button
          type="button"
          title="Remove Member"
          onClick={() => fields.remove(index)}
        />
        <h4>Member #{index + 1}</h4>
        <Field
          name={`${member}.firstName`}
          type="text"
          component={renderField}
          label="First Name"
        />
        <Field
          name={`${member}.lastName`}
          type="text"
          component={renderField}
          label="Last Name"
        />
        <FieldArray name={`${member}.hobbies`} component={renderHobbies} />
      </li>
    ))}
  </ul>
)

const FieldArraysForm = props => {
  const {handleSubmit, pristine, reset, submitting} = props
  return (
    <form onSubmit={handleSubmit}>
      <Field
        name="clubName"
        type="text"
        component={renderField}
        label="Club Name"
      />
      <FieldArray name="members" component={renderMembers} />
      <div>
        <button type="submit" disabled={submitting}>Submit</button>
        <button type="button" disabled={pristine || submitting} onClick={reset}>
          Clear Values
        </button>
      </div>
    </form>
  )
}

export default reduxForm({
  form: 'fieldArrays', // a unique identifier for this form
})(FieldArraysForm)

【讨论】: