sajad torkamani

Here’s an example of how to handle file uploads with React (CodeSandbox).

import { useRef, useState } from 'react'

const App: React.FC = () => {
  const [selectedFile, setSelectedFile] = useState<File | null>(null)
  const fileInputRef = useRef<HTMLInputElement | null>(null)
  const [downloadLink, setDownloadLink] = useState<string | null>(null)

  function handleAddAttachment() {
    if (!fileInputRef.current) {
      return
    }

    fileInputRef.current.click()
  }

  function handleRemoveAttachment() {
    setSelectedFile(null)
    if (downloadLink) {
      window.URL.revokeObjectURL(downloadLink)
    }
  }

  function handleFileChange(event: React.ChangeEvent<HTMLInputElement>) {
    // event.target.files is a FileList object
    // (https://developer.mozilla.org/en-US/docs/Web/API/FileList)
    const files = event.target.files

    // Each item in FileList is a File object
    // https://developer.mozilla.org/en-US/docs/Web/API/File
    const file = files && files[0] ? files[0] : null

    console.log(file)

    setSelectedFile(file)
    if (file) {
      setDownloadLink(window.URL.createObjectURL(file))
    }
  }

  function getFileType(mimeType: string): string {
    const subtype = mimeType.split('/')[1]

    if (typeof subtype === 'undefined') {
      return 'Unknown'
    }

    if (subtype.includes('ms-powerpoint')) {
      return 'Powerpoint'
    }

    if (subtype.includes('ms-word')) {
      return 'Word doc'
    }

    if (subtype.includes('ms-excel')) {
      return 'Spreadsheet'
    }

    return subtype.toUpperCase()
  }

  return (
    <main className="px-4 my-6">
      <button
        className="border border-gray-400 px-3"
        onClick={handleAddAttachment}
      >
        Attach file
      </button>

      {selectedFile && (
        <>
          <button
            className="block text-sm mt-1 text-red-600"
            onClick={handleRemoveAttachment}
          >
            Remove file
          </button>

          {downloadLink && (
            <a
              href={downloadLink}
              className="block text-sm mt-1 text-indigo-600"
              download={selectedFile.name}
            >
              Download file
            </a>
          )}
        </>
      )}

      <input
        ref={fileInputRef}
        type="file"
        name="file"
        onChange={handleFileChange}
        className="hidden"
      />

      {selectedFile && (
        <div className="mt-4">
          <h2 className="text-xl font-bold mb-1">File details</h2>
          <ul className="list-disc pl-8">
            <li>File name: {selectedFile.name}</li>
            <li>File mime type: {selectedFile.type}</li>
            <li>File type: {getFileType(selectedFile.type)}</li>
            <li>File download link: {downloadLink}</li>
          </ul>
        </div>
      )}
    </main>
  )
}

export default App