Home > Software engineering >  File upload with react and typescript
File upload with react and typescript

Time:08-31

I am trying to build a simple single select upload component. On click of a button that has a hidden input field, I open the file dialog then I select a file. The placeholder changes to the file name and then a change and clear button. Everything works fine, but on click of clear the file dialog, I dont want it to open on clear. It should open when "Choose file to upload" and "Change" is clicked. Can someone help?.

I am using material UI for the same

Sandbox: https://codesandbox.io/s/react-hook-upload-oxqdp2?file=/src/Upload.tsx:0-1784

import * as React from "react";
import { Button } from "@material-ui/core";
import { useState } from "react";

interface UploaderProps {
  fileType?: string | AcceptedFileType[];
}

enum AcceptedFileType {
  Text = ".txt",
  Gif = ".gif",
  Jpeg = ".jpg",
  Png = ".png",
  Doc = ".doc",
  Pdf = ".pdf",
  AllImages = "image/*",
  AllVideos = "video/*",
  AllAudios = "audio/*"
}

export const Upload = (props: UploaderProps) => {
  const { fileType } = props;
  const acceptedFormats: string | AcceptedFileType[] =
    typeof fileType === "string"
      ? fileType
      : Array.isArray(fileType)
      ? fileType?.join(",")
      : AcceptedFileType.Text;
  const [selectedFiles, setSelectedFiles] = useState<File | undefined>(
    undefined
  );

  const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
    setSelectedFiles(event?.target?.files?.[0]);
  };

  const onUpload = () => {
    console.log(selectedFiles);
  };

  return (
    <>
      <Button
        variant="contained"
        component="label"
        style={{ textTransform: "none" }}
      >
        <input
          hidden
          type="file"
          accept={acceptedFormats}
          onChange={handleFileSelect}
        />
        {!selectedFiles?.name && <span> Choose file to upload</span>}
        {selectedFiles?.name && (
          <>
            <span style={{ float: "left" }}> {selectedFiles?.name}</span>
            <span style={{ padding: "10px" }}> Change</span>
            <span onClick={() => setSelectedFiles(undefined)}>Clear</span>
          </>
        )}
      </Button>
      <Button
        color="primary"
        disabled={!selectedFiles}
        style={{ textTransform: "none" }}
        onClick={onUpload}
      >
        Upload
      </Button>
    </>
  );
};

CodePudding user response:

You should prevent default behavior of event. It worked for me like this:

<span onClick={(e) => { e.preventDefault(); setSelectedFiles(undefined); }}>Clear</span>
  • Related