How to Create a Custom File Upload Button in React with TypeScript

·

3 min read

Creating a custom file upload button in React allows for more control over styling and user experience compared to the default file input. However, styling the default file input is often a hassle. No worries, though! This tutorial will guide you through creating a custom file upload button that easily integrates with a hidden file input element.

To access the full source code for this tutorial, visit the sandbox here. This article was originally posted here.

Customizing the Input

First, we need to set up our hidden file input and create a button to trigger it. By using React's useRef hook, we can programmatically access and interact with the hidden input element. Here's how you can do it.

import { useRef, useState } from "react";
import "./styles.css";

export default function App() {
  const inputRef = useRef<HTMLInputElement>(null);

  function handleFileUpload(e: React.ChangeEvent<HTMLInputElement>) {
    const files = e.target.files;
    if (!files) return;

    const file = files[0];

    // use the file
    console.log(file.name);
  }

  function handleButtonClick(e: React.MouseEvent<HTMLButtonElement>) {
    e.preventDefault();
    if (!inputRef || !inputRef.current) return;

    inputRef.current.click();
  }

  return (
    <form>
      <button onClick={handleButtonClick}>Upload File</button>
      <input ref={inputRef} type="file" hidden onChange={handleFileUpload} />
    </form>
  );
}

Instead of displaying the default file input, this approach hides the input element and uses a button to trigger the file selection dialog.

Let’s breakdown of how this works:

  1. Hidden File Input and Custom Button

    • The input element of type file is hidden using the hidden attribute.

    • A button element is provided for the user to click, which will trigger the file selection dialog.

    • The ref (inputRef) is created using useRef and attached to the hidden input element. This allows us to programmatically interact with the input element.

  2. Handling Button Click.

    • The handleButtonClick function is triggered when the button is clicked.

    • e.preventDefault() is called to prevent the form from submitting, which would otherwise cause a page reload.

    • The function then checks if the inputRef exists. If so, it programmatically clicks the input element by calling inputRef.current.click(). This action opens the file selection dialog.

  3. Handling File Selection:

    • When the user selects a file, the handleFileUpload function is triggered by the onChange event of the input element.

    • Inside handleFileUpload, we check if any files were selected by the user. If so, we access the first file from the files list (files[0]).

Typically, within handleFileUpload, additional logic would be implemented to handle the selected file. This could include storing the file in state, uploading it to a server, or displaying it in the UI.

Styling the Button

To further improve the UI, we can style the button. You can add these styles to a styles.css file and then import it in your component as shown in the earlier snippet.

button {
  background-color: rgb(223, 223, 223);
  border: none;
  border-radius: 50px;
  padding: 10px 15px;
  font-weight: 600;
  cursor: pointer;
}

Okay, that’s it. 🚀 By leveraging React's useRef hook and event handling, we can trigger a file upload dialog with a styled button instead of the default file input.