Design Converter
Education
Developer Advocate
Last updated on Nov 7, 2024
Last updated on Nov 6, 2024
In this article, you'll learn how to build a file upload feature for a React app using Material UI (MUI) and Axios. You'll cover creating the upload button, handling uploads with Axios, and styling components with MUI. The article also explores using Higher Order Components (HOCs) for reusability. In the end, find out how DhiWise streamlines the web app development process even further with its unique features.
In web development, enabling file upload functionality is essential for creating interactive, data-driven apps. Whether it’s images, documents, or other file types, a smooth file upload process elevates user experience and engagement. This guide dives into creating a powerful file upload feature in React using Material UI (MUI) components—often known as “React MUI file upload.”
React, a highly popular JavaScript library, offers a flexible, component-based approach to building interfaces, while Material UI brings in pre-styled components that align with Google’s Material Design principles.
By merging these two, you can deliver a polished, efficient file upload experience that’s both user-friendly and visually appealing. Let’s get started on implementing this essential feature in your React application.
Before we dive into the code, let's set up our React project. Install Node.js and npm (Node Package Manager) on your machine if you haven't already. Once installed, you can create a new React project by running the following command in your terminal:
1npx create-react-app mui-file-upload
This command will create a new React project named "mui-file-upload". Navigate into the project directory using cd mui-file-upload and open the project in your preferred code editor.
Next, we need to install Material UI and Axios. Material UI will provide us with pre-built React components that follow Material Design principles, while Axios is a promise-based HTTP client for making requests to our server.
To install these libraries, run the following commands in your terminal:
1npm install @material-ui/core 2npm install axios
After installing, we can import the necessary components and functions from these libraries at the top of our React files.
Now, let's create a file upload button in React. We'll start by importing the necessary components from Material UI:
1import React from 'react'; 2import Button from '@material-ui/core/Button';
Next, we'll create a new function component named UploadButton:
1export default function UploadButton() { 2 return ( 3 <Button variant="contained" color="primary" component="span"> 4 Upload 5 </Button> 6 ); 7}
In this code, we're using the Button component from Material UI. We set the variant prop to "contained" to give the button a filled background and the color prop to "primary" to apply the primary color theme. The component prop is set to "span" to render the button as a span element. This button doesn't do anything yet, but we'll add functionality in the following sections.
Material UI provides two types of button components: Button and IconButton. The Button component is used for buttons with text labels, while the IconButton is used for icons.
The Button component can take a variety of props, including variant, color, and size, allowing for a high degree of customization. The IconButton on the other hand, is more minimalist and is typically used for navigation or UI control actions.
Here's an example of how to use the IconButton component:
1import IconButton from '@material-ui/core/IconButton'; 2import PhotoCamera from '@material-ui/icons/PhotoCamera'; 3 4export default function IconButtons() { 5 return ( 6 <IconButton color="primary" aria-label="upload picture" component="span"> 7 <PhotoCamera /> 8 </IconButton> 9 ); 10}
We use the IconButton component with the PhotoCamera icon in this code. The color prop is set to "primary", and the aria-label prop is used for accessibility.
Material UI allows for extensive customization of its components. For example, you can change the color, size, and variant of the Button component. You can also add icons and adjust the button's padding and margin.
Here's an example of a customized Button component:
1import Button from '@material-ui/core/Button'; 2import CloudUploadIcon from '@material-ui/icons/CloudUpload'; 3 4export default function UploadButton() { 5 return ( 6 <Button 7 variant="contained" 8 color="primary" 9 startIcon={<CloudUploadIcon />} 10 > 11 Upload 12 </Button> 13 ); 14}
In this code, we're using the startIcon prop to add an icon to the start of the button. The CloudUploadIcon is imported from Material UI's icon library.
Next, let's create a Material UI file upload form. This form will contain an input field for selecting files and a button for initiating the upload.
First, we'll import the necessary components:
1import React from 'react'; 2import Button from '@material-ui/core/Button'; 3import TextField from '@material-ui/core/TextField'; 4
Then, we'll create a new function component named UploadForm:
1export default function UploadForm() { 2 return ( 3 <form> 4 <TextField type="file" /> 5 <Button variant="contained" color="primary" component="span"> 6 Upload 7 </Button> 8 </form> 9 ); 10}
In this code, we're using the TextField component for the file input field and the Button component for the upload button. The type prop of the TextField component is set to "file" to allow for file selection.
To handle file upload, we'll use Axios, a promise-based HTTP client. Axios allows us to make HTTP requests from the browser to the server, and it supports the Promise API.
First, let's import Axios:
1import axios from 'axios'; 2
Next, we'll create a function to handle the file upload:
1const handleFileUpload = (event) => { 2 const file = event.target.files[0]; 3 const formData = new FormData(); 4 formData.append('file', file); 5 6 axios.post('/upload', formData) 7 .then(response => { 8 console.log(response); 9 }) 10 .catch(error => { 11 console.error(error); 12 }); 13}; 14
In this function, we're creating a new FormData object and appending the selected file to it. Then, we're making a POST request to the '/upload' endpoint with the form data. The server should handle the file upload and return a response.
After a file is uploaded, it's a good practice to provide feedback to the user. One common way to do this is by displaying a progress bar. Material UI provides a LinearProgress component for this purpose.
First, let's import the LinearProgress component:
1import LinearProgress from '@material-ui/core/LinearProgress'; 2
Next, we'll create a state variable to keep track of the upload progress:
1const [uploadProgress, setUploadProgress] = React.useState(0); 2
Then, we'll update the handleFileUpload function to update the uploadProgress state variable:
1axios.post('/upload', formData, { 2 onUploadProgress: (progressEvent) => { 3 const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total); 4 setUploadProgress(percentCompleted); 5 } 6}) 7
Finally, we'll display the LinearProgress component in our render method:
1<LinearProgress variant="determinate" value={uploadProgress} /> 2
In this code, the variant prop is set to "determinate" to indicate that the progress value is known, and the value prop is set to the uploadProgress state variable.
During the file upload process, various errors may occur. For instance, the file might be too large, the file type might not be supported, or the server might be down.
Handling these errors gracefully and providing informative feedback to the user is essential.
Let's update our handleFileUpload function to handle errors:
1axios.post('/upload', formData, { 2 onUploadProgress: (progressEvent) => { 3 const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total); 4 setUploadProgress(percentCompleted); 5 } 6}) 7.then(response => { 8 console.log(response); 9}) 10.catch(error => { 11 console.error(error); 12 // handle error here 13}); 14
In the catch block, we're logging the error to the console. In a real application, you might want to display an error message to the user or take other appropriate actions.
Material UI provides a powerful styling solution called makeStyles that allows you to write CSS in JavaScript. With makeStyles, you can create a hook that generates a class name map, which you can then use to style your components.
Here's an example of how to use makeStyles to style our file upload component:
1import { makeStyles } from '@material-ui/core/styles'; 2 3const useStyles = makeStyles((theme) => ({ 4 root: { 5 '& > *': { 6 margin: theme.spacing(1), 7 }, 8 }, 9 input: { 10 display: 'none', 11 }, 12})); 13 14export default function UploadButtons() { 15 const classes = useStyles(); 16 17 return ( 18 <div className={classes.root}> 19 <input 20 accept="image/*" 21 className={classes.input} 22 id="contained-button-file" 23 multiple 24 type="file" 25 /> 26 <label htmlFor="contained-button-file"> 27 <Button variant="contained" color="primary" component="span"> 28 Upload 29 </Button> 30 </label> 31 32 ); 33} 34
In this code, we're using the makeStyles function to create a useStyles hook. We then call this hook inside our UploadButtons component to generate the class names. Finally, we apply these class names to our elements using the className prop.
A higher-order component (HOC) in React is a function that takes one component and returns another with additional properties or behavior. HOCs are useful for abstracting and reusing component behavior.
We can create a HOC that adds file upload functionality to any component. Here's an example:
1function withFileUpload(WrappedComponent) { 2 return class extends React.Component { 3 handleFileUpload = (event) => { 4 // handle file upload here 5 }; 6 7 render() { 8 return ( 9 <WrappedComponent 10 onFileUpload={this.handleFileUpload} 11 {...this.props} 12 /> 13 ); 14 } 15 }; 16}
In this code, withFileUpload is a HOC that adds a handleFileUpload method to the wrapped component. The wrapped component can then use this method to handle file upload.
React and Material UI (MUI) provide a powerful combination for implementing file upload functionality. React's component-based architecture allows for modular and reusable code, while Material UI provides a wide array of pre-built components that adhere to Material Design principles.
Additionally, by using Axios for handling HTTP requests, we can easily handle file upload and download with a promise-based API. This makes our code more readable and easier to reason about.
Finally, by implementing file upload in a higher-order component, we can abstract the file upload functionality and reuse it across different components. This leads to cleaner and more maintainable code.
Overall, React, Material UI, and Axios provide a robust set of tools for implementing file upload functionality in a web application. However, DhiWise takes the entire process of app development even further by providing a visual interface for designing your application's UI.
This means you can create and customize components to build the layout for your file upload feature, including the upload button and progress bar. DhiWise will automatically generate code components and integrate seamlessly with the concepts covered in this article.
Here's how DhiWise can specifically help:
Faster Development: Visually designing your UI eliminates the need for manual coding of component layouts, saving you time and effort.
Reduced Complexity: DhiWise handles the underlying code for UI components, keeping your code cleaner and easier to maintain.
Reusable Components: DhiWise allows you to create reusable components for your file upload functionality, promoting code maintainability and consistency across your application.
By combining the strengths of React, Material UI, Axios, and DhiWise, you can develop robust and visually appealing file upload features for your web applications with exceptional efficiency.
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.