LogoDTreeLabs

Mutators in react final form

Gaurav SinghBy Gaurav Singh in ReactFinal FormJavaScript on January 27, 2022

React final form provides its custom solution to manage the form state but sometimes we need to update/add the state for the fields which are not there on the form. We need to implement custom mutators for these cases. For example, if we want to submit a value but its corresponding field is not there on the form then we need to implement the custom mutator to update the state. Let's consider the following form where we want to add fullName to the submitted values -

const App = () => {
  return (
    <Form
      onSubmit={onSubmit}
      render={({form, handleSubmit}) => {
        return(
          <form onSubmit={handleSubmit}>
            <label>First Name</label>
            <Field
              name="firstName"
              component="input"
              type="text"
              placeholder="First Name"
            />
            <label>Last Name</label>
            <Field
              name="lastName"
              component="input"
              type="text"
              placeholder="Last Name"
            />
            <button type="submit" disabled={submitting || pristine}>
              Submit
            </button>
          </form>
        );
      }}
    />
  );
};

When we submit the form following values get submitted -

{
  "firstName": "First",
  "lastName": "Last",
}

If we want to add more field to form state then we need to define a custom mutator setFormAttribute to update the form. We can extract this function in some utils also which can be used with multiple forms.

<Form
  onSubmit={onSubmit}
  mutators={{
    setFormAttribute: ([fieldName, fieldVal], state, { changeValue }) => {
      changeValue(state, fieldName, () => fieldVal);
    }
  }}
/>

And now we can use this using form.mutators.setFormAttribute.

Now, let's say we want to submit the fullName without adding the fullName field to the form. We need to add an event handler to the <Field> element and call the mutator inside the component.

<Field
  name="firstName"
  component="input"
  type="text"
  placeholder="First Name"
>
  {({ input, meta }) => {
    return (
      <input
        {...input}
        onChange={(e) => {
          // we will discuss event handling in upcoming articles.
          input.onChange(e); //final-form's onChange
          if (handleChange) {
            form.mutators.setFormAttribute("fullName", `${values.firstName} ${values.lastName}`);
          }
        }}
      />
    );
  }}
</Field>

Making custom changes in the React final form can be a bit overwhelming at times :). That's why we've added the complete demo of the component below. Do check it out.

Demo: https://codesandbox.io/s/affectionate-goldstine-0csfv

NPM Package: React Final Form

You can connect with us on Twitter for your feedback or suggestions.