How to validate an image in redux-form

      Posted by Pourya Dashtegolipour on Feb 7, 2019 in Tech Corner

      A couple of weeks ago, we came across an issue when validating images using redux-form. Not only did we have to validate the format and size of the image file but also its width and height. Looking around the web there was no clear, well-explained solution to the problem, so… here’s one! This is how you validate an image in redux-form

      In this tutorial, we will learn how to validate both image format and the file size, width and height of an image. 


      The main limitation we faced was as a result of all the elements stored in a file object, including: lastModified, lastModifiedDate, name, size, type, webkitRelativePath and of course __proto__. As you see, these are not enough for us to validate the width and height of an image.

      Prerequisites: 🎨

      1. Create a react app.
      2. Add redux and redux-form as dependencies
      3. Connect redux and react
      4. Add semantic-ui-react to access its nice UI components [this step is optional].

      Step 1:

      First, let’s import all the necessary stuff at the top, such as ReactPropTypesFieldreduxFormButton and Form. As mentioned before, using Semantic UI is totally optional. In our Field we’ll have to pass our own component so that we can catch onChange events in the code below- it is written as this.renderFileInput and is explained later in this post.

      Next, add the prop types and default props. And then a simple tiny form, a field and a submit button, as in the code below:

      import React from "react";
      import PropTypes from "prop-types";
      import { Field, reduxForm } from "redux-form";
      import { Button, Form } from "semantic-ui-react";
      class SimpleForm extends React.Component {
          static propTypes = {
              previewLogoUrl: PropTypes.string,
              mimeType: PropTypes.string,
              maxWeight: PropTypes.number,
              maxWidth: PropTypes.number,
              maxHeight: PropTypes.number,
              // redux-form props
              handleSubmit: PropTypes.func.isRequired
          static defaultProps = {
              previewLogoUrl: "",
              mimeType: "image/jpeg, image/png",
              maxWeight: 100,
              maxWidth: 100,
              maxHeight: 100
          render() {
              const {
              } = this.props;
                              ///validation methods go here!///
      export default reduxForm({
        form: "simple"

      Step 2:

      Let’s add those validation methods. First the easiest (file size); to do that just get the input file object and retrieve size from it. Then you can convert the size to kilobytes, megabytes or anything you want! Add your validation criteria and send an error message.

      validateImageWeight = imageFile => {
          if (imageFile && imageFile.size) {
            // Get image size in kilobytes
            const imageFileKb = imageFile.size / 1024;
            const { maxWeight } = this.props;
            if (imageFileKb > maxWeight) {
              return `Image size must be less or equal to ${maxWeight}kb`;

      Next, file format; this one’s really simple too; to do that just retrieve type from file object and validate it. 😊 #lazywriting

      validateImageFormat = imageFile => {
          if (imageFile) {
            const { mimeType } = this.props;
            if (!mimeType.includes(imageFile.type)) {
              return `Image mime type must be ${mimeType}`;

      Next, width and height. To achieve this, we’ll have to catch any onChangeevent from our redux field, construct a URL object (let’s call it imageObject) with our input file object (let’s call this imageFile), check image width and height from the URL object and finally store width and height in our input file object.

      Field Component:

      renderFileInput = ({ input, type, meta }) => {
          const { mimeType } = this.props;
          return (
                onChange={event => this.handleChange(event, input)}
              {meta && meta.invalid && meta.error && (
                  <Message negative header="Error:" content={meta.error} />

      Change Handler:

      handleChange = (event, input) => {
          let imageFile =[0];
          if (imageFile) {
              const localImageUrl = URL.createObjectURL(imageFile);
              const imageObject = new window.Image();
              imageObject.onload = () => {
                  imageFile.width = imageObject.naturalWidth;
                  imageFile.height = imageObject.naturalHeight;
              imageObject.src = localImageUrl;

      Width and Height Validations:

      validateImageWidth = imageFile => {
          if (imageFile) {
            const { maxWidth } = this.props;
            if (imageFile.width > maxWidth) {
              return `Image width must be less or equal to ${maxWidth}px`;
        validateImageHeight = imageFile => {
          if (imageFile) {
            const { maxHeight } = this.props;
            if (imageFile.height > maxHeight) {
              return `Image height must be less or equal to ${maxHeight}px`;

      What happens now, once an image is selected by our input field, an onChangeevent is invoked, which in result will create a URL object from our image file, retrieve its width and height, sort them in the imageFile object and call the onChange once again but this time our imageFile object has width and height set in them! Next, the validation methods will be called by redux form validation just like a normal validation method. 


      You can check the complete code below:


      Hope someone out there finds this helpful.



      The original version of this post can be found on Strands Tech Corner on Medium 


      If you are interested in finding out how Strands can help your bank, or if you would like to get a Free Demo of our AI-powered Financial Management solutions, please fill out this form and one of our Sales Reps will get back to you as soon as possible.



      Get Our Newsletter

      Subscribe to our exclusive weekly newsletter to stay up to date on
      FinTech trends, insights, and analysis