Search code examples
reactjsreduxreact-reduxmobx-react-form

Redux Forms - Ignore initialValues with no registered field


I have an object fetched from the server that contains lots of fields not relevant to the current form. I'd like to pass the whole object to initialValues on my form, but when I submit, I don't want the extra fields to carry through.

Here's a simple form:

const MyForm = ({ handleSubmit }) => (
  <form onSubmit={handleSubmit}>
    <Field name="name" component="input" placeholder="Name" />
    <button type="submit">Submit</button>
  </form>
);

export default reduxForm({
  form: "foo",
  onSubmit: values => {
    console.log(values);
  },
})(MyForm);

And in its parent component, it's rendered like so:

<MyForm initialValues={{ name: "bob", other: "thing" }} />

When I submit the form, I want values to look like:

{name: "bob"}

and not include the extra other field. Is this possible?

Since the extra fields are not visible to the end user, they shouldn't be part of the form's eventual patch request. I also don't want my parent component to have be coupled tightly to the form, so I don't want to filter the fields at that level.


Solution

  • We ended up solving this by wrapping the form with a higher-order component. You can then wrap the passed-in submission handler and perform some logic on the values returned by the form before they get sent to the submission handler:

    export function specialForm(WrappedForm) {
    
      return class extends Component {
        submissionFilter(submitFunction) {
          return function(values, dispatch, props) {
            // Only let registered fields through.
            if (props.registeredFields) {
              values = _.pick(values, Object.keys(props.registeredFields));
            }
    
            return submitHandler(values, dispatch, props)
          }
        }
    
        render() {
          var submitHandler = this.props.onSubmit;
          if (submitHandler) {
            submitHandler = this.submissionFilter(submitHandler);
          }
          return <WrappedForm {...this.props} onSubmit={submitHandler} />;
        }
      };
    }
    

    The key to making this work is the fact that the form's props are passed as the 3rd argument to the submission handler, and the props have an attribute called registeredFields which are the fields in the form itself.