Upload a File / Multiple Files in React | React.js Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everyone and welcome to this tutorial so today what I'm going to be showing you is how you can upload a file or multiple files in react using axios or fetch and how you can update the UI as the upload progresses whether that be text and or a progress bar so this is the app that I'm going to be working with to create it before this tutorial I ran the MPX create the act tap command to do this you need to make sure that you have node installed on your system because it relies upon node package manager so if you haven't already you need to install node and then in the project folder that it creates icd'd into it and once in there installed axios and then to start the development server ran npm start so I've done this already and my development server is running on localhost Port 3000 so I cleared the unnecessary files that come with create react app and in app.js in the jsx that's being returned I edited it so there's an input of type file and a button which when clicked will initiate the upload so first I want to make a file that user selects available to the button so that when it's clicked an upload can begin so I'll start with the setup or a single file so when a user selects a file on the input element the change event will occur and the function that you pass in to the JavaScript logic here will fire and you can select the input element without touching the Dom via the target property on the event object that's generated and the file that uses selected is available on the files property on a file list though because it's a single file it will be at index position zero now to make the selected file available when the upload button is clicked we can create a value that is available throughout the component and is updated live using the native use State hook so I'll set the reference for the value to be file and the reference or the updating function to set file and I'll set the initial value or file to be null and update this value using the updating function every time a user selects a new file now we can listen out or a click on the button with or click and the function that's passed into here will run when this occurs so I'll Define the function externally because there's quite a lot of logic related to the upload to go inside here and inside on click you just place a reference to the function definition that will be called when the click occurs you don't call the function in there and the first thing that you want to do inside the function is check if a user has already selected a file if they haven't then you want to return to exit out of the handle upload function so the subsequent uploading code doesn't run so if this next bit of code runs then the user has selected a file and we can prepare payload so to do that I'm going to append the file to a form data object a form data object is useful here because it will set the post request headers automatically it also supports multiple files which will be taking advantage of after this initial request and it can be recognized and processed across various back-end programming environments because it's sent in the same format as a HTML form that includes file data now for the request itself I'm first going to post the data with axios and the reason is that unlike Fetch with axios which uses the XML HTTP request object under the hood sometimes referred to that's the Ajax object you can get upload progress as a percentage at least at the time of this recording this isn't possible with fetch and the advantage of working with axios over the underlying Ajax object is that it has a much simpler and more modern promise based syntax so I'm going to make the post request to a live test API for making HTTP requests that sends back in its response what you sent to it so we can check if it was successful and also see the file or files that we sent in the second argument position you place the payload which in this case is the newly created form date for object and to get upload progress you pass in as a third argument an object with an unupload progress property on it the value is a function which will fire every time there is progress on the upload and to get the current progress that's available on an event object on a parameter passed in to the function so to get a progress percentage multiply by 100 and if you want set any headers then create a header's property the name and value of each header should be defined in string format inside an object now you don't need to set a content type header here because the payload is a form data object this will be set for you to multi-part form data in fact if you try setting it manually it can lead to an error so it's best not right setting it now when the response comes back from the servers is promise based so the result can be accessed inside the then method the data is available on a data property on the response object and if there's an error the catch method will fire and our log whatever error comes through to the console now to what date the UI as the upload progresses I'm going to create two new state values the first one I'll set the value to progress and the initial value of progress on me and object with two properties the first one is going to be a true or false value indicating whether the upload has started and the second a value or the percentage complete and the second new bit of state that I'm going to create will contain the message that should currently be displayed in the UI so before setting are these values are going to be displayed in the UI I'll update their values at appropriate points in the code so I want a message to be displayed just before the post request is made so there is immediately a message displayed in the UI when a user clicks upload the reason that I don't set it in the upload progress function is that there is a delay between request starting and upload progress being registered the next message to be registered is when the upload has completed successfully or it's failed though I still want to log the data to the console that's just for us and if there's an error again I want to log to the console and that message now for the two property values of progress I want to set the value of started the true immediately before any upload progress is returned now when updating a state value that is an object there can be problems with the updating of the properties throughout the component though to avoid that you can use the current value of the state which you have available to you as a parameter in a function so the updated value of State here is going to be the return value which is an object into which I'm spreading all of the properties of the current state value and you just update those properties that you want to set to a new value so started to true and for the progress we're going to get the global State value and use that to return a new object that consists of the previous and an updated value or the percentage property now every time one of the updating functions is called it will trigger a re-render so we can use these values to update the UI so we'll do some conditional rendering using some JavaScript logic so the progress bar doesn't appear in the UI before the upload has started so the right hand side of the logical and operator will only return if the value of its left hand side is true so if I render a progress bar on its right hand side it will only appear when it has started so you might want to import a custom progress bar or create your own one using CSS Here For Speed I'm going to be using the native HTML progress element and the second item that I want to conditionally render is a span element that will contain a message when one is set so I'll save this and let's test it in the browser so that we can see upload progress or clearly I'll simulate a slow 3g connection so when I click on upload the message is rendered you can't see the progress bar yet because that will only be visible when upload is clicked with a file selected and that's because only then is the started value set true so the progress bar is updating messages are rendering as expected and if we take a look data that's being echoed back we have as expected an image and if we take a look at the headers you can see that the content type header was set for us to multiply form data and our custom header was set now to make this a multiple file upload then there are a few changes that you need to make the first one is I'll add the multiple attribute to the input element to support multiple file selection and instead of setting the file value to the file on the file list at index position 0 alt pass in the file list and inside the handle upload function I still want to check if the user has selected a file and if not exit out of the handle upload function now I want to append each of the files on the file list to the form data object so for each and map are not available on a file list so I'm using a loop instead so for the name String of each file that I append I'm using backticks because that allows me to insert the looping variable like this plus one because the looping variable starts at zero and the file that I want to append is the one on the file list at the index position or the looping variable and that's it we don't have to make any changes to the request because the payload is the form data object with the file data attached everything else stays the same as it did when we were uploading a single file so this time right to upload two files so the UI loaded as expected and if we take a look at the data two files were received by the server now finally I'll show you how you can make the upload using fetch so with fetch you don't get upload progress so I'll comment out the progress bar from the UI now you might be wondering why use fetch when you can't get upload progress so an advantage of batch is that the headers on the response are received before the body of the response is read though what this means is that you can return the success message before waiting for the response body like you do with axios so if you're not concerned about a progress bar you might want to use batch instead so because the syntax is very similar I'll edit the axios request to make it a batch request so with fetch the payload is included on a body property I'm going to clear the on upload progress property because we don't need that this time and also the setting of progress above headers are set in the same way now for the response object so only the headers are immediately available so if we receive a successful status code from the server then the value of ok is going to be true if not then I want row an error that will cause the function in the catch method to run then if it's successful then I read the body of response that is in Json format to JavaScript object format and the result of that is available as a parameter in a function passed in to an additional then method so let's test this I'll upload both files foreign successful you notice there's a bit of a delay in between the success message and the data being logged to the console and that's because we were able to read the headers before reading the body of the response and you can see here that server received both files our custom header is set and again the content type header was set for us because the payload is a form data object so that is it for this tutorial I hope you found it useful if you did please consider hitting the like button down below this video it helps us with the algorithm and others to find this video and if you'd like to see more content like this from us in the future don't forget you can subscribe to the channel
Info
Channel: OpenJavaScript
Views: 15,365
Rating: undefined out of 5
Keywords:
Id: ijx0Uqlo3NA
Channel Id: undefined
Length: 18min 19sec (1099 seconds)
Published: Fri May 26 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.