Formik: Simply Handling Images/Files Upload

Photo by Sigmund on Unsplash

Formik: Simply Handling Images/Files Upload

·

2 min read

In my previous post titled Formik: How to set initialValues from API I explained briefly what Formik is and why I chose it over React form.

Moreover, in this post, I am going to share a tip for handling files or images upload. Working with file upload in Formik requires a workaround using onChange to set the value to the file in addition to declaring our HTML input tag as the file which we generally do without much effort.

Uploading a Single File

import React, { useCallback } from 'react';
import { Formik, Form, useField, useFormikContext, FormikHelpers } from 'formik';
import { FormLabel, FormGroup, FormControl } from 'react-bootstrap';

const FileUpload = () => {
  const [_, meta, helpers] = useField('file');
  const { error } = meta;
  const { touched } = useFormikContext();
  const isInvalid = touched && !!error;
  const isValid = touched && !error;

  const handleSubmit = useCallback(
    (
      values: FormValues, 
      { setSubmitting }: FormikHelpers<FormValues>
    ) => {
      setSubmitting(false);
      // your code to handle uploading files to server via api
  }, []);

  return (
    <Formik
      enableReinitialize={true}
      initialValues={{ file: null }}
      onSubmit={handleSubmit}
    >
     <Form>
        <FormGroup classname="mb-3" controlid="file">
          <FormLabel>Select a File:</FormLabel>
          <FormControl 
            name="file" 
            type="file" 
            onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
              helpers.setValue(event.currentTarget.files[0]);
            }}
            {...{ isInvalid, isValid }}
          />
            <FormControl.Feedback type="invalid">{error}</FormControl.FeedBack>
          </FormControl>
        </FormGroup>
     </Form>
    </Formik>
  )
};

export { FileUpload };

Like I already mentioned above, the important piece of code that we should concentrate is onChange method inside FormControl where we use Formik helpers method to set a file value. This is because Formik doesn't support file upload by default.

Let's see an extract onChange method:

onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
  helpers.setValue(event.currentTarget.files[0]);
}}

So, now you can select a file from a Formik. What if you want to upload multiple files? That can be done as similarly as selecting a file. You will just need to pass file values to the helpers method and the rest of the component is the same. That's pretty much it!

Uploading Multiple Files

Let's see a code snippet of onChange method for uploading multiple files. Here, we pass all files to the helper method instead of a single file (event.currentTarget.files[0]).

onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
  helpers.setValue(event.currentTarget.files);
}}

Conclusion

Handling files upload in Formik requires a bit more work than a common input tag with type as the file. But, that is not discouraging me not using Formik in my current project as the tweak is pretty simple and has huge benefits from Formik.