File Upload with Preview

Loading

File upload with preview is a common feature in modern web applications, allowing users to upload files (images, documents, etc.) and preview them before submitting. In React, this can be easily implemented using React hooks (useState, useEffect) and the FileReader API to display image previews.

Here’s how you can implement file upload with preview functionality in React:


1. Simple File Upload with Image Preview

This example allows users to upload an image and see a preview of it before submitting.

Step-by-Step Example:

import React, { useState } from 'react';

const FileUploadWithPreview = () => {
  const [selectedFile, setSelectedFile] = useState(null);
  const [previewUrl, setPreviewUrl] = useState(null);

  // Handle file selection and preview generation
  const handleFileChange = (e) => {
    const file = e.target.files[0];
    if (file) {
      setSelectedFile(file);

      // Generate preview URL for image files
      const reader = new FileReader();
      reader.onloadend = () => {
        setPreviewUrl(reader.result);
      };
      reader.readAsDataURL(file);
    }
  };

  // Handle form submission (optional)
  const handleSubmit = (e) => {
    e.preventDefault();
    if (selectedFile) {
      console.log('File submitted:', selectedFile);
      // You can add logic to upload the file here
    }
  };

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <label htmlFor="file-upload">Upload a file: </label>
        <input
          type="file"
          id="file-upload"
          onChange={handleFileChange}
          accept="image/*" // You can specify file types (e.g., image/*)
        />

        {/* Display the image preview */}
        {previewUrl && (
          <div>
            <h3>Preview:</h3>
            <img
              src={previewUrl}
              alt="File preview"
              style={{ width: '200px', height: 'auto', border: '1px solid #ddd', marginTop: '10px' }}
            />
          </div>
        )}

        {/* Submit button */}
        <button type="submit" disabled={!selectedFile}>
          Submit
        </button>
      </form>
    </div>
  );
};

export default FileUploadWithPreview;

Explanation:

  • State Management: selectedFile holds the selected file, and previewUrl stores the URL of the file for the preview.
  • File Reader: FileReader is used to generate a data URL (readAsDataURL) for the selected file, which is then used as the src of the img tag for the preview.
  • Preview Rendering: If the preview URL exists (previewUrl), an image preview is shown.
  • File Acceptance: The accept="image/*" attribute restricts the file input to only images, but you can customize this as needed.

2. Handling Multiple File Uploads with Preview

If you want to handle multiple file uploads (e.g., images) with previews, you can extend the logic to manage multiple files.

Example: Multiple File Upload with Previews

import React, { useState } from 'react';

const MultipleFileUploadWithPreview = () => {
  const [selectedFiles, setSelectedFiles] = useState([]);
  const [previewUrls, setPreviewUrls] = useState([]);

  // Handle multiple file selection and preview generation
  const handleFileChange = (e) => {
    const files = Array.from(e.target.files);
    const newPreviewUrls = files.map((file) => URL.createObjectURL(file));

    setSelectedFiles(files);
    setPreviewUrls(newPreviewUrls);
  };

  // Handle form submission (optional)
  const handleSubmit = (e) => {
    e.preventDefault();
    console.log('Files submitted:', selectedFiles);
    // You can add logic to upload files here
  };

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <label htmlFor="file-upload">Upload multiple files: </label>
        <input
          type="file"
          id="file-upload"
          onChange={handleFileChange}
          accept="image/*" // Restrict to image files
          multiple // Allow multiple files
        />

        {/* Display image previews */}
        {previewUrls.length > 0 && (
          <div>
            <h3>Previews:</h3>
            <div style={{ display: 'flex', gap: '10px' }}>
              {previewUrls.map((url, index) => (
                <img
                  key={index}
                  src={url}
                  alt={`File preview ${index + 1}`}
                  style={{ width: '100px', height: 'auto', border: '1px solid #ddd' }}
                />
              ))}
            </div>
          </div>
        )}

        {/* Submit button */}
        <button type="submit" disabled={selectedFiles.length === 0}>
          Submit
        </button>
      </form>
    </div>
  );
};

export default MultipleFileUploadWithPreview;

Explanation:

  • Multiple Files: The multiple attribute allows users to select more than one file at a time.
  • Handling Multiple Files: handleFileChange manages an array of files, and URL.createObjectURL generates a URL for each selected file, which is used to display the preview.
  • Rendering Previews: The previews are displayed in a row using CSS flex to align the images horizontally.

3. Advanced Features: File Size and Type Validation

You may want to restrict the type of files users can upload and validate file sizes (e.g., limiting uploads to images under 2MB).

Example: File Validation (Type and Size)

import React, { useState } from 'react';

const FileUploadWithValidation = () => {
  const [selectedFile, setSelectedFile] = useState(null);
  const [previewUrl, setPreviewUrl] = useState(null);
  const [error, setError] = useState('');

  // Handle file selection, validate type and size
  const handleFileChange = (e) => {
    const file = e.target.files[0];

    if (file) {
      if (file.size > 2 * 1024 * 1024) {
        setError('File size exceeds 2MB');
        return;
      }

      if (!file.type.startsWith('image/')) {
        setError('Only image files are allowed');
        return;
      }

      setError('');
      setSelectedFile(file);

      // Generate preview for valid files
      const reader = new FileReader();
      reader.onloadend = () => {
        setPreviewUrl(reader.result);
      };
      reader.readAsDataURL(file);
    }
  };

  // Handle form submission (optional)
  const handleSubmit = (e) => {
    e.preventDefault();
    console.log('File submitted:', selectedFile);
    // Logic to upload file here
  };

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <label htmlFor="file-upload">Upload a file: </label>
        <input
          type="file"
          id="file-upload"
          onChange={handleFileChange}
          accept="image/*"
        />
        {error && <div style={{ color: 'red' }}>{error}</div>}

        {/* Display image preview */}
        {previewUrl && (
          <div>
            <h3>Preview:</h3>
            <img
              src={previewUrl}
              alt="File preview"
              style={{ width: '200px', height: 'auto', border: '1px solid #ddd', marginTop: '10px' }}
            />
          </div>
        )}

        {/* Submit button */}
        <button type="submit" disabled={!selectedFile || error}>
          Submit
        </button>
      </form>
    </div>
  );
};

export default FileUploadWithValidation;

Explanation:

  • File Size Validation: We check the file size and ensure it does not exceed 2MB.
  • File Type Validation: We ensure the file type starts with image/ to restrict uploads to image files only.
  • Error Handling: If there’s an error, we display an error message, and the form submission button remains disabled until the error is resolved.

Leave a Reply

Your email address will not be published. Required fields are marked *