Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

258
Vistas
File upload with react and typescript

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>
    </>
  );
};

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

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

<span onClick={(e) => { e.preventDefault(); setSelectedFiles(undefined); }}>Clear</span>
about 4 years ago · Juan Pablo Isaza Denunciar

0

I would use useRef hook to refer to the hidden input field, something like this for example:

import * as React from 'react';
import Button from '@mui/material/Button';

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

export default function Upload({ fileType }) {
  const fileRef = React.useRef();
  const acceptedFormats =
    typeof fileType === 'string'
      ? fileType
      : Array.isArray(fileType)
      ? fileType?.join(',')
      : AcceptedFileType.Text;

  const [selectedFiles, setSelectedFiles] = React.useState();

  const handleFileSelect = (event) => {
    setSelectedFiles(event?.target?.files?.[0]);
  };

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

  const onClear = () => {
    setSelectedFiles(undefined);
  };

  const onUpdate = (event) => {
    if (event.target.textContent.trim().toLowerCase() === 'change') {
      onClear();
      fileRef.current.click();
      return;
    }
    if (event.target.textContent.trim().toLowerCase() === 'clear') {
      onClear();
      return;
    }
  };

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

See working demo: https://stackblitz.com/edit/react-dmzlsq?file=demo.js

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda