1
votes

I have a multistep form with a submit button at the bottom of each section and a clickable list of the sections for navigation. I have implemented an auto submit feature that runs if a user updates information and then navigates away using the menu without clicking the submit button:

 const AutoSubmit = () => {
   const { dirty, submitForm } = useFormikContext();
   React.useEffect(() => {
     if (dirty) {
       submitForm();
     }
   }, [dirty, submitForm]);
   return null;
 };

The issue is that if the Yup validation fails then the submission is obviously blocked and any information on the previous section is lost. Essentially what i'm trying to do is trigger full validation if a user clicks the actual submit button, but do a partial validation (i.e. no required fields) if its an auto submit so their progress can be saved.

Ive tried using setFieldValue to set an "autoSubmit: true" flag in the above component and then changed the Yup Schema to only require fields etc if its not there or false, but it doesn't seem to pick up the value in time for the submission (presumably something to do with it running when the component is unmounting). Anyone got any ideas on how to get this working?

Thanks

1

1 Answers

0
votes

So i had a bit of a rethink of this and thought i should post my solution just in case anyone finds it useful. I essentially decided to bypass the Formik validation for the partial submit, and let the backend handle it. As this was going to be a silent submit, the user feedback of the validation wasn't required, and because its assuming some data may be missing etc, it seems like something the backend should be deciding on.

The only other problem was that Formik re-renders every time any of the form data changes. My requirement was to only trigger this partial submit when the user navigated away from the form section, so my example above wasn't suitable as it would fire on every re-render. To get around this i used a ref and put the function outside of Formik:

function FormComponent() {
  const formRef = useRef();

  useEffect(() => {
    return async () => {
      const {dirty, isSubmitting, values} = formRef.current;

      if (!isSubmitting && dirty) {
        try {
          await doPartialSubmission(values);
        } catch (error) {
          // Handle error
        }
      }
    };
  }, [formRef])

  return (
    <Formik
      innerRef={formRef}
      onSubmit={doFullValidatedSubmit()}
    >
      //Standard formik stuff...
    </Formik>
  );
};