Austin Roy Omondi Live long and prosper 👌

Building a file upload component with react-uploady and Ant Design

4 min read 1395

Building a file upload component with react-uploady and Ant Design

When it comes to the usage of any website, user input is key and in many sites today a user may be required for one reason or another to upload a file to the website. This can be anything from images for a new user profile to diagnostic files needed to help users troubleshooting on a help forum. For this reason, it is crucial to make the file upload process as easy and seamless for the user. You need to allow the user to quickly access their file picker, choose files, upload them, and get feedback on the status of their upload. This is where react-uploady comes in to save the day.

The react-uploady library is built to be simple yet customizable and allows us to create and customize the view of our uploader to our liking. Developers using the library can keep it simple and just use it plug and play or they can also customize the entire upload flow. For this article, we’ll be making use of Ant Design which provides a library of well built and customizable React UI components to create a simple yet appealing uploader component that allows us to open the file explorer and pick out files to upload.

Why use react-uploady?

You may be wondering why a developer may be inclined to use react-uploady over other file uploader libraries so let us look at some of the advantages react-uploady has that other libraries don’t.

  • It is customizable — the developer is provided with several options around how to set up their uploader with the package allowing them to tailor the upload process to their liking, they are provided with the ability to use as-is or create custom UI, they can show download progress and previews among other options
  • The library is very lightweight with various pieces separated to cut down on unnecessary package installs. For instance, if a developer wishes to monitor and show upload previews or progress, they may install the packages concerned with each part separately and leave out those they do not need, leading to a much lighter bundle size

Creating our uploader

Application setup

First, let’s bootstrap our application with create-react-app, if you do not have it installed already you can do so by running:

npm install -g create-react-app

Now you can create your application by running:

create-react-app react-uploady-demo

We have a few dependencies that we will need for our application, to install them, run this command:

yarn add @rpldy/uploady @rpldy/sender antd

These packages are:

  • @rpldy/uploady– The react-uploady main package, it contains an uploady context provider as well as hooks that expose the functionality of the uploader and other advanced features and data for client apps
  • @rpldy/sender – The default XHR request sender for react-uploady, we are using it in our case to mock a sent request rather than set up an actual server request. We are doing this by creating a mock enhancer, which we will cover later in this article
  • antd– The Ant Design Component library

Creating our Uploader component

Create an Uploader.js file and create an Uploader functional component as shown below:

//Uploader.js
import React, { useState, useCallback, useContext } from "react";
import "./App.css";
import Uploady, { useItemProgressListener, UploadyContext } from "@rpldy/uploady";
import { createMockSender } from "@rpldy/sender";
import { Button, Progress } from "antd";

const Uploader = () => {
  return (
    <Uploady
      destination={{ url: "http://mock-server.com" }}
      enhancer={mockEnhancer}
    >
      <div className="Uploader">
        <CustomButton />
        <br />
        <br />
        <UploadProgress />
      </div>
    </Uploady>
  );
}
const mockEnhancer = uploader => {
  const mockSender = createMockSender({ delay: 1000 });
  uploader.update({ send: mockSender.send });
  return uploader;
};

export default Uploader;

In the code above we import the Uploady component which is the context provider from react-uploady. It allows us to configure our upload options such as the destination as well as any enhancers we may want to add.

The destination prop takes an object that configures the endpoint to which we will send the uploaded file. in our case, we are simply providing a URl but this is where you can set request parameters, methods, and headers that you may need for your request.

We made a custom demo for .
No really. Click here to check it out.

The enhancer prop on the other hand takes an enhancer function which we can use to change the behavior of our uploader. For instance, this is where you can add a function that tells the uploader to retry any failed downloads. In our case, we are feeding in a mockEnhancer function created using createMockSender that tells our uploader that the upload has been successfully sent after 1000 milliseconds. For more on enhancers check out the documentation on enhancers.

You will have also noticed we have two missing components, CustomButton and UploadProgress, let us create these two now.

Creating the upload button

Our upload button is a simple functional component that is granted access to the UploadyContext using React’s useContext hook and uses it to open the native file browser to select a file to send to the server. This process is triggered by clicking a custom button from Ant Design which calls the handleUpload function that we define in the component. To do this we add the following code into Uploader.js:

const CustomButton = () => {
    const uploady = useContext(UploadyContext);
    const hanldeUpload = useCallback(()=> {
            uploady.showFileUpload();
        },[uploady]);
    return <Button onClick={hanldeUpload} type="primary">Custom Upload Button</Button>
}

Monitoring and showing upload progress

Providing the user with feedback on how the upload process is going is key when trying to create a good user experience and a good way to do this is displaying the progress of the download through a progress bar or some similar UI. In our case, we will go with the Progress component from Ant Design, specifically the circular variant, and this is how we can go about it.

Add the following functional component to Uploader.js:

const UploadProgress = () => {
  const [progress, setProgess] = useState(0);
  const progressData = useItemProgressListener();
  if (progressData && progressData.completed > progress) {
    setProgess(() => progressData.completed);
  }
  return (
    progressData && (
      <Progress
        type="circle"
        percent={progress}
      />
    )
  );
};

Four our progress UI we got the current progress from the uploader using the useItemProgressListener hook from react-uploady. This hook listens for and captures the progress information of each download from the sender, we then save this progress into state and feed it into the Progress component which will show the amount of the upload that has been done all the way to completion. We, of course, hide this component when there is no ongoing upload.

Styling and wrapping up

The last step for us is to add some CSS to ensure that our components are placed nicely in the browser then add our Uploader component to the main App.js file so that it may be displayed. Add these few lines to App.css to center the components and space them out a little:

.Uploader{
  padding: 5rem;
  margin: 0 auto;
}

Now let us update App.js by replacing all the create-react-app boilerplate code with these few lines:

import './App.css';
import 'antd/dist/antd.css';
import Uploader from './Uploader'
function App() {
  return (
    <div className="App">
      <Uploader />
    </div>
  );
}
export default App;

And that’s it! We are all set to go! Startup your application with yarn start and watch the magic!

You can check out the final application here.

Conclusion and suggestions

With this information, you are all set to get started using react-uploady in your React application to create intuitive user upload components. This is, however, just one method the package provides to upload files with the library also supporting drag and drop inputs as well as uploading files from a given URL. The library also supports a number of senders such as chunked XHR requests and using the TUS protocol. It would be almost impossible to take a deep dive into all the above methods in just a single article and I would recommend checking out the guides and documentation as you make use of react-uploady. The maintainers were also kind enough to create a Storybook with several examples of varying complexity.

There are, of course, other steps you may take to further improve your uploader’s UX such as creating resumable downloads and providing user feedback with toasts. Hopefully, you can build on the knowledge picked up in this article and you can look into these improvements and more.

Full visibility into production React apps

Debugging React applications can be difficult, especially when users experience issues that are hard to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.

LogRocket is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your React apps — .

Austin Roy Omondi Live long and prosper 👌

Leave a Reply