Skip to main content

React File Upload

 In this article, we’ll cover how to enable file uploads in your React app from scratch. If you want a simple plug & play solution, try our React Filepicker Component (you’ll need to create a free Filestack account to get your API key).

Understanding the File Upload Process in React:

Uploading files in a React app, such as images, documents, or any other file types, typically follows a structured approach:

  1. User File Selection: The journey begins with allowing the user to select a file. In React, this is commonly achieved by utilizing the <input> element with its type attribute set to “file”. This offers a user-friendly interface for file selection. When a file is chosen, it’s important to have an event handler in place. This event handler listens to any changes or interactions with the file input and updates the application’s state with the selected file’s information.
  2. Server Communication: Once the file information is captured and stored in the application’s state, the next pivotal step is sending it over to a server. This could be for processing, storage, or any other backend operation. Tools like axios or the native fetch API are frequently employed to handle this communication. They aid in making asynchronous HTTP requests to servers. It’s crucial to wrap the selected file in a FormData object, ensuring the data is properly formatted for transmission.
  3. Feedback & Response Handling: Upon initiating communication with the server, always anticipate two outcomes: success or failure. Implementing feedback mechanisms like success messages, error alerts, or even displaying the uploaded file helps improve user experience. It provides assurance that their action (file upload) was successful or gives clarity if something went amiss.
  4. Error Handling: The digital realm isn’t always predictable. Issues might arise during the upload process, be it network glitches, file format mismatches, or server-side errors. Being prepared with a robust error-handling mechanism not only aids in troubleshooting but also ensures users aren’t left in the dark. Informative error messages and alternative solutions can steer users in the right direction.
  5. External Libraries and Tools: While React provides a solid foundation, sometimes external libraries or tools can expedite the development process. Tools like axios simplify HTTP communications. Moreover, services like Filestack offer out-of-the-box file uploading solutions, saving development time.

By adhering to this structured approach, developers can ensure a smooth and efficient file upload process in their React applications, enhancing both functionality and user satisfaction.

Now let’s dive in to the nitty gritty details.

We’re starting with a freshly created react app with the default content removed.

import './App.css';

function App() {
  return (
    <div className="App">

    </div>
  );
}

export default App;
C#

The first thing we’ll do is create a simple form where our user can choose what file to upload.

import './App.css';
function App() {
  return (
    <div className="App">
        <form>
          <h1>React File Upload</h1>
          <input type="file" />
          <button type="submit">Upload</button>
        </form>
    </div>
  );
}

export default App;
C#

Next, we’ll create a state variable, add an onChange event handler to the input element, and create a handleChange function to keep track of what file our user chose to upload

import './App.css';
import React, {useState} from react;

function App() {

  const [file, setFile] = useState()

  function handleChange(event) {
    setFile(event.target.files[0])
  }

  return (
    <div className="App">
        <form>
          <h1>React File Upload</h1>
          <input type="file" onChange={handleChange}/>
          <button type="submit">Upload</button>
        </form>
    </div>
  );
}

export default App;
C#

Now that we know what file our user chose to upload, we’ll add axios for making http requests, an onSubmit event handler to the form, and a handleSubmit function to upload the file using a http POST request.

import './App.css';
import React, {useState} from 'react';
import axios from 'axios';

function App() {

  const [file, setFile] = useState()

  function handleChange(event) {
    setFile(event.target.files[0])
  }

  function handleSubmit(event) {
    event.preventDefault()
    const url = 'http://localhost:3000/uploadFile';
    const formData = new FormData();
    formData.append('file', file);
    formData.append('fileName', file.name);
    const config = {
      headers: {
        'content-type': 'multipart/form-data',
      },
    };
    axios.post(url, formData, config).then((response) => {
      console.log(response.data);
    });

  }

  return (
    <div className="App">
        <form onSubmit={handleSubmit}>
          <h1>React File Upload</h1>
          <input type="file" onChange={handleChange}/>
          <button type="submit">Upload</button>
        </form>
    </div>
  );
}

export default App;
C#

This is the critical step when enabling file uploads using React. We’ve created a config object to specify a ‘content-type’ header for our http request. In order to upload files, the ‘content-type’ header must be set to ‘multipart/form-data’.

new FormData() creates a new empty formData object that we send as the payload in our POST request. Our POST request assumes there is an API endpoint on our backend server at http://localhost:3000/uploadFile.

Uploading Multiple Files

In many real-world applications, there’s a need for users to upload more than one file at a time. Let’s enhance our React app to support multiple file uploads.

import './App.css';
import React, { useState } from 'react';
import axios from 'axios';

function App() {
  const [files, setFiles] = useState([]);
  const [uploadedFiles, setUploadedFiles] = useState([]);

  function handleMultipleChange(event) {
    setFiles([...event.target.files]);
  }

  function handleMultipleSubmit(event) {
    event.preventDefault();
    const url = 'http://localhost:3000/uploadFiles';
    const formData = new FormData();
    files.forEach((file, index) => {
      formData.append(`file${index}`, file);
    });

    const config = {
      headers: {
        'content-type': 'multipart/form-data',
      },
    };

    axios.post(url, formData, config)
      .then((response) => {
        console.log(response.data);
        setUploadedFiles(response.data.files);
      })
      .catch((error) => {
        console.error("Error uploading files: ", error);
      });
  }

  return (
    <div className="App">
      <form onSubmit={handleMultipleSubmit}>
        <h1>React Multiple File Upload</h1>
        <input type="file" multiple onChange={handleMultipleChange} />
        <button type="submit">Upload</button>
      </form>
      {uploadedFiles.map((file, index) => (
        <img key={index} src={file} alt={`Uploaded content ${index}`} />
      ))}
    </div>
  );
}

export default App;
C#

In this snippet, the

input
C#

tag now has the 

multiple
C#

attribute, allowing users to select multiple files. We're iterating over the selected files, adding each one to our 

FormData
C#

object, and then displaying each uploaded file in the app.

File Upload Progress

Another enhancement is to provide users with feedback on the progress of their file upload.

import './App.css';
import React, { useState } from 'react';
import axios from 'axios';

function App() {
  const [file, setFile] = useState();
  const [uploadProgress, setUploadProgress] = useState(0);

  function handleChange(event) {
    setFile(event.target.files[0]);
  }

  function handleSubmit(event) {
    event.preventDefault();
    const url = 'http://localhost:3000/uploadFile';
    const formData = new FormData();
    formData.append('file', file);

    const config = {
      headers: {
        'content-type': 'multipart/form-data',
      },
      onUploadProgress: function(progressEvent) {
        const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
        setUploadProgress(percentCompleted);
      }
    };

    axios.post(url, formData, config)
      .then((response) => {
        console.log(response.data);
      })
      .catch((error) => {
        console.error("Error uploading file: ", error);
      });
  }

  return (
    <div className="App">
      <form onSubmit={handleSubmit}>
        <h1>React File Upload with Progress</h1>
        <input type="file" onChange={handleChange} />
        <button type="submit">Upload</button>
        <progress value={uploadProgress} max="100"></progress>
      </form>
    </div>
  );
}

export default App;
C#

Here, we’ve added an onUploadProgress function to our Axios config. This function updates our uploadProgress state variable with the current percentage of the upload. We display this percentage using the HTML5 progress element.

These enhancements not only provide a better user experience but also cater to more practical use cases in file uploading scenarios. Now let’s move forward to displaying the uploaded file.

Displaying the Uploaded File in the React App

After successfully uploading a file, it’s often beneficial for the user to get feedback and see the file they just uploaded. In this section, we’ll update the state with the uploaded file’s URL and display the file in our React app.

import './App.css';
import React, {useState} from 'react';
import axios from 'axios';

function App() {

  const [file, setFile] = useState()
  const [uploadedFileURL, setUploadedFileURL] = useState(null)

  function handleChange(event) {
    setFile(event.target.files[0])
  }

  function handleSubmit(event) {
    event.preventDefault()
    const url = 'http://localhost:3000/uploadFile';
    const formData = new FormData();
    formData.append('file', file);
    formData.append('fileName', file.name);
    const config = {
      headers: {
        'content-type': 'multipart/form-data',
      },
    };
    axios.post(url, formData, config).then((response) => {
      setUploadedFileURL(response.data.fileUrl);
    });
  }

  return (
    <div className="App">
        <form onSubmit={handleSubmit}>
          <h1>React File Upload</h1>
          <input type="file" onChange={handleChange}/>
          <button type="submit">Upload</button>
        </form>
        {uploadedFileURL && <img src={uploadedFileURL} alt="Uploaded content"/>}
    </div>
  );
}

export default App;
C#

In this snippet, we added a new state variable uploadedFileURL which holds the URL of the uploaded file. After we get a successful response from the server, we update this state variable with the file’s URL which we then use to display the image in our application.

 

Handling React File Upload Errors

It’s good practice to handle potential errors that might occur during the file upload process. Let’s add some error handling to our handleSubmit function:

import './App.css';
import React, {useState} from 'react';
import axios from 'axios';

function App() {

  const [file, setFile] = useState();
  const [uploadedFile, setUploadedFile] = useState();
  const [error, setError] = useState();

  function handleChange(event) {
    setFile(event.target.files[0]);
  }

  function handleSubmit(event) {
    event.preventDefault();
    const url = 'http://localhost:3000/uploadFile';
    const formData = new FormData();
    formData.append('file', file);
    formData.append('fileName', file.name);
    const config = {
      headers: {
        'content-type': 'multipart/form-data',
      },
    };
    axios.post(url, formData, config)
      .then((response) => {
        console.log(response.data);
        setUploadedFile(response.data.file);
      })
      .catch((error) => {
        console.error("Error uploading file: ", error);
        setError(error);
      });
  }

  return (
    <div className="App">
        <form onSubmit={handleSubmit}>
          <h1>React File Upload</h1>
          <input type="file" onChange={handleChange}/>
          <button type="submit">Upload</button>
        </form>
        {uploadedFile && <img src={uploadedFile} alt="Uploaded content"/>}
        {error && <p>Error uploading file: {error.message}</p>}
    </div>
  );
}

export default App;
C#

In the above code, we’ve added a catch block to our axios POST request that sets an error state variable in case of an error. We also render an error message to the screen if there was an error uploading the file.

By extending our application with these two sections, we’ve made it more user-friendly and robust. It’s now not only possible for users to upload files, but also to view the uploaded files and receive error messages in case something goes wrong during the upload process.

Comments

Popular posts from this blog

.NET Core API With Dapper, Repository And UnitOfWork

  Introduction In this tutorial, you will use ASP.NET Core Web API to create a web API that returns a list of brands. This article focuses on creating web API using dapper, repository pattern, and UnitOfWork pattern in .NET 8. I will guide you through the steps by step to create web API. HTTP is not just for serving up web pages. HTTP is also a powerful platform for building APIs that expose services and data. HTTP is simple, flexible, and ubiquitous. Almost any platform that you can think of has an HTTP library, so HTTP services can reach a broad range of clients, including browsers, mobile devices, and traditional desktop applications. ASP.NET Core Web API is a framework for building web APIs on top of the .NET Framework. Creating a New Project in Visual Studio Launch Visual Studio and select Create a New Project. Creating a Core Web API Start Visual Studio and choose Create a new project. In the Create a new project dialog, select ASP.NET Core Web API Click Next. Configuring You...

.Net framework interview questions

What is the .NET Framework? The .NET Framework is a set of technologies that form an integral part of the .NET Platform. It is Microsoft’s managed code programming model for building applications. The .NET Framework has two main components: Common Language Runtime (CLR): The CLR is one of the foundation in the .NET framework and provides a common set of services for applications developed on Microsoft .Net Technologies. .NET Framework class library: The .NET framework class library is a collection of reusable types and exposes features of the runtime. It contains of a set of classes that is used to access common functionality. What is CTS (Common Type System)? The common type system (CTS) defines how types are declared, used, and managed in the runtime, and is also an important part of the runtime’s support for cross-language integration. The common type system performs the following functions: ·          Establishes a framework that...

Move Selected Gridview Rows to Another Gridview in Asp.net

Introduction :  Here I will explain how to move or transfer selected checkbox gridview rows to another  grid v iew in asp.net using c#, vb.net or copy one gridview row to another gridview in asp.net using c#, vb.net. Description :  In previous posts I explained Display images in gridview from database in asp.net, Enable/Disable checkbox in gridview based on condition,  asp.net gridview examples  and  bind data to textbox control in gridview ,  Bind data to dropdownlist  in gridview  and many articles relating to  asp.net,  c#, vb.net, c#,vb.net. Now I will explain how to move selected rows from one gridview to another gridview in asp.netusing c#, vb.net. To implement this first we need to write the code in aspx page like this  < html   xmlns ="http://www.w3.org/1999/xhtml"> < head > ...