ReactHustle

React: How to Preview Images Before Uploading

Jasser Mark Arioste

Jasser Mark Arioste

React: How to Preview Images Before Uploading

In this tutorial, you'll learn how to preview images selected by the user in React step-by-step.

Introduction #

When uploading images, sometimes we want to preview the images selected by the user for a better user experience. 

Three Main Steps #

There are three main steps to implementing image preview in React:

  1. Get the input from the user via <input type="file"/> element or Drag and Drop API. In this tutorial, we'll use the <input type="file"/> element.
  2. Read the files using the URL.createObjectURL function and transform them into dataUrl. You can also use the FileReader API but that's a bit more complicated.
  3. Once we have the dataUrl, we can pass them to an image preview component to display to the user.

Final Output #

Here's the final output of what we'll be making today.

React Preview Image - Final Output

Step 1 - Getting Input From the User #

First, we have to know what the images we have to display are. To do that, we can use the <input type="file"/> element and listen to the onChange event. Let's create a component for this so create the file components/ImageFileInput.tsx and copy the code  below:

// components/ImageFileInput.tsx
type Props = {
  onFilesChange(files: File[]): void;
};

const ImageFileInput = ({ onFilesChange }: Props) => {
  return (
    <input
      type="file"
      accept="image/*" // only accept image file types
      multiple // allow multiple images
      onChange={(e) => {
        // this gives us the data on what files are selected
        // however, it's of type `FileList` which is hard to modify.
        const fileList = e.target.files;
        // let's convert `FileList` into a `File[]`
        if (fileList) {
          const files = [...fileList]; // now we have `File[]` type
          // This only works on es6 version make sure to set your tsconfig.json "target" to "es6"
          onFilesChange(files);
        }
      }}
      className="bg-gray-100"
    />
  );
};
export default ImageFileInput;

123456789101112131415161718192021222324252627

Explanation.

We listen to the onChange event and check the value of e.target.files. But e.target.files is of type FileList which is hard to process. On line 17, we check if the value is not null and convert the fileList into a File[] type using the spread operator.

Usage:

To use this component, we just have to listen to the onFilesChange event. For example:

import ImageFileInput from "@/components/ImageFileInput";
import { useState } from "react";

export default function Home() {
  // track the files selected using a useState hook.
  const [files, setFiles] = useState<File[]>([]);

  return (
    <main className="p-24">
      <ImageFileInput
        onFilesChange={(selectedFilies) => setFiles(selectedFilies)}
      />
      {/* iterate through the files and display the name */}
      {files.map((file, i) => {
        return <p key={i}>{file.name}</p>;
      })}
    </main>
  );
}
12345678910111213141516171819

Once files are selected we display the filename for each image. Here's the output:

React preview image tutorial - Step 1

Step 2 - Transforming Data #

Now that we have data, we can't display them as images as is. We have to transform them to dataUrl using the URL.createObjectURL method. 

import ImageFileInput from "@/components/ImageFileInput";
import { useState } from "react";
import Image from "next/image";
export default function Home() {
  const [files, setFiles] = useState<File[]>([]);

  // transform files into data urls
  const urls = files.map((file) => URL.createObjectURL(file));

  return (
    <main className="p-24">
      <ImageFileInput
        onFilesChange={(selectedFilies) => setFiles(selectedFilies)}
      />
      {/* iterate through the urls and display the images */}
      {urls.map((url, i) => {
        const filename = files[i].name; // image-1.jpg
        console.log(url); // blob:http://localhost:3000/ea1f5af2-d00f-4090-a4c9-538799f065d2
        return (
          <Image src={url} height={300} width={240} key={i} alt={filename} />
        );
      })}
    </main>
  );
}
12345678910111213141516171819202122232425

Explanation: 

On line 12, we map through the files and use the URL.createObjectURL method for each file. This returns a URL that we can use as an image source. 

That's basically it! The output should be the same as our final output.

Conclusion #

You learned step-by-step how to implement a preview image component for React. The URL.createObjectURL provides an easy way to transform files into URLs. The next step would be to style the file input and the image previews to look good. Then maybe the next step is to implement a form and add an onSubmit handle to upload the images to an external database or API.

If you like this tutorial, please leave a like or share this article. For future tutorials like this, please subscribe to our newsletter or follow me on GitHub.

Resources #

Credits: Image by Jörg Vieli from Pixabay

Share this post!

Related Posts

Disclaimer

This content may contain links to products, software and services. Please assume all such links are affiliate links which may result in my earning commissions and fees.
As an Amazon Associate, I earn from qualifying purchases. This means that whenever you buy a product on Amazon from a link on our site, we receive a small percentage of its price at no extra cost to you. This helps us continue to provide valuable content and reviews to you. Thank you for your support!
Donate to ReactHustle