Drag and dropping files in React using react-dropzone

Sdílet
Vložit
  • čas přidán 27. 07. 2024
  • This video will use the react-dropzone library to allow users to drag and drop files, see previews, and upload files to Cloudinary.
    👉🏼 The Ultimate NextJs course
    🔗 www.hamedbahram.io/courses/ne...
    👉🏼 Project source code
    🔗 github.com/HamedBahram/dropzo...
    👉🏼 react-dropzone library
    🔗 react-dropzone.js.org
    CHAPTERS
    0:00 Intro
    0:38 Project setup
    1:00 Adding react-dropzone
    6:00 File preview
    11:00 Preventing memory leaks
    12:30 Restricting file size or type
    15:00 Handling rejected files
    20:15 Uploading files to Cloudinary
    25:35 Outro

Komentáře • 74

  • @mariocesena2277
    @mariocesena2277 Před 8 měsíci +2

    Hamed, huge thanks for the awesome tutorials! You didn't just whip up a useful component, but you also broke it down and threw in some great tips. Keep the cool stuff coming our way!

    • @hamedbahram
      @hamedbahram  Před 8 měsíci

      You're welcome Mario! Thanks for your comments man. I appreciate it.

  • @raminkhodaie4063
    @raminkhodaie4063 Před 8 měsíci +1

    very usefull content for me, I was looking for something like this.TNX a lot Hamed

  • @ZawCodes
    @ZawCodes Před 5 měsíci +1

    exactly what I was looking for, very helpful

  • @ahrenwagner2993
    @ahrenwagner2993 Před rokem +5

    This is honestly one of the greatest things on the internet.
    You teach very well. Thanks so much, I was trying to do something exactly like this and couldn't find anything until this.

    • @hamedbahram
      @hamedbahram  Před rokem +1

      Thanks for your kind feedback, Ahren! I'm glad you found the video helpful.

    • @ahrenwagner2993
      @ahrenwagner2993 Před rokem

      @@hamedbahram For sure! Thanks for taking the time to create this video!

    • @hamedbahram
      @hamedbahram  Před rokem

      @@ahrenwagner2993 my pleasure!

  • @NazaninSoleimanian
    @NazaninSoleimanian Před 2 měsíci +1

    huge thanks for the awesome tutorials!

  • @dancelifevarsha4109
    @dancelifevarsha4109 Před 6 měsíci +1

    Thank you very much sir. This video saved my day.

  • @ngshung9352
    @ngshung9352 Před rokem +1

    Excellent information

  • @AliBagheri2079
    @AliBagheri2079 Před rokem

    دمت گرم✌❤❤

  • @dimitrisiwannidis5561
    @dimitrisiwannidis5561 Před 9 měsíci +1

    Excellent explanation, Thank you !

    • @hamedbahram
      @hamedbahram  Před 9 měsíci

      You are welcome! Glad it was helpful.

  • @aryansrivastava6692
    @aryansrivastava6692 Před 11 měsíci +1

    Hey man real thanks for this insightful video about react dropzone and cloudinary. I have a question can we upload multiple files at the same time using cloudinary

    • @hamedbahram
      @hamedbahram  Před 11 měsíci

      Yeah I think you'd have loop over your files and make multiple requests.

  • @mayank19saxena
    @mayank19saxena Před rokem +3

    Thanks for amazing lesson! I have a question - I am unable to access the preview property in Files object in the JSX. The error that I am getting is "Property 'preview' does not exist on type 'File' " Have done the exact same approach that you have mentioned in the video. just that my project supports react typescript.

    • @hamedbahram
      @hamedbahram  Před rokem +1

      You'd have to manually add preview to each file using `URL.createObjectURL(file)`

    • @mayank19saxena
      @mayank19saxena Před rokem +1

      @@hamedbahram I'll try this out.

    • @savadaniel622
      @savadaniel622 Před 5 měsíci

      @@mayank19saxena Or you could use a custom type for this. First define the custom type like this type UploadedFile = File & { preview: string }; and then, where you have the useState do something like this const [files, setFiles] = useState([]);

  • @Kiswood
    @Kiswood Před 10 měsíci +1

    Hi, what if I wanted to save these files to a local database (i.e., a folder on my desktop) would that be possible? I wanted to use this to for an MVP I'm creating:
    - Drag and drop files, save to local folder (mock database) using React Dropzone
    - Run a python code that goes into that folder and executes code

    • @hamedbahram
      @hamedbahram  Před 10 měsíci

      Saving files locally won't really work once you deploy your app to serverless platforms like Vercel. You should use a real data base or a media cloud provider to store your files. You can look into this for file storage => www.bytescale.com

  • @jritzeku
    @jritzeku Před 11 měsíci +1

    What if we need to get all the urls for multiple images? Atm, we upload multiple images to cloudinary but only get back one url for a single image. Ideally, would like to have array of image urls which then can be sent to backend api to store in some DB. I've tried to store image urls via state after getting back data but when i access it, the state array is not yet populated with the urls.

    • @hamedbahram
      @hamedbahram  Před 11 měsíci

      You'd need to loop through your form files and upload them one by one to cloudinary, get the url, maybe push it to an array, and at the end write to your database.

    • @jritzeku
      @jritzeku Před 11 měsíci

      @@hamedbahram
      Yea I tried that but the issue is that it doesnt wait for the state array to be populated hence just empty array.
      const handleSubmit = async (e) => {
      e.preventDefault()
      if (!files?.length) return
      console.log('files:', files)
      files.forEach(async (file) => {
      const formData = new FormData()
      formData.append('file', file)
      formData.append('upload_preset', presetKey)
      axios
      .post(
      `api.cloudinary.com/v1_1/${cloudName}/image/upload`,
      formData
      )
      .then((res) => setImgUrls((prevVal) => [...prevVal, res.data]))
      .catch((err) => console.error(err))
      })
      //does NOT WAIT until the loop is completely done above to populate the state array
      console.log('Sending img url to my backend server...')
      console.log('imgUrls', imgUrls)//[ ]
      }

  • @wheeiraeth
    @wheeiraeth Před 10 měsíci +1

    Hi thanks for the tutorial! I am also using this method of having a separate state for the selected files so as to allow removal of files and selecting files one by one. However I have one issue - when I use the maxFiles property, this property is tied to the acceptedFiles from react-dropzone, which means that if my maxFiles = 3, and I select one by one, I can still end up selecting more than 3, because acceptedFiles "refreshes" each time we select a file. Do you have a solution for this? Thanks again!

    • @hamedbahram
      @hamedbahram  Před 10 měsíci

      You can pass a custom validator function where you can check the number of current files in your local state and throw an error if it exceeds your maximum number of files.

    • @wheeiraeth
      @wheeiraeth Před 10 měsíci +1

      @@hamedbahram Thanks for the quick reply! Yes I did see that, but I am not able to access the number of files that the user is about to select. For example let's say max is 3. If the user already selected 2, and is now about to select another 2, that shouldn't be allowed, but if he is about to select 1 it should be allowed. However interestingly, I was able to set maxFiles dynamically like 3-files.Length (where files is my custom useState for the files). That worked like a charm!

    • @hamedbahram
      @hamedbahram  Před 10 měsíci +1

      @@wheeiraeth Sweet!

  • @beccaowens5765
    @beccaowens5765 Před 11 měsíci +1

    Thank you, Hamed. Is there a way to set a minimum image width and height?

    • @hamedbahram
      @hamedbahram  Před 11 měsíci

      Not out of the box, but I guess you can implement it using a custom validator. Something like this:
      ```
      function imageDimensionValidator(file) {
      const image = new Image()
      image.onload = function () {
      console.log(this.width, this.height)
      }
      image.src = URL.createObjectURL(file)
      }
      ```

  • @mikeoxlong9618
    @mikeoxlong9618 Před rokem +1

    For some reason it tells me "Unexpected end of input" at res.json, my syntax seems to be correct though

    • @hamedbahram
      @hamedbahram  Před rokem

      Not sure why that is Mike. You can pull down my code and compare it to yours.

  • @AbdelaliBennadji
    @AbdelaliBennadji Před rokem +1

    After the Droping of pictures, how can i save them until the work finish, without a database pls

    • @hamedbahram
      @hamedbahram  Před rokem

      I'm not sure if I understand the question. Can you explain what you mean by saving the files until work is finish without a database? where do you want to save the files? In the video I save the files in my cloud storage (Cloudinary) and get a URL back which I can write to my database later.

  • @DEVil-kf5wj
    @DEVil-kf5wj Před 4 měsíci +1

    hey i wanted upload audio instead of images what major changes i have to make?

    • @hamedbahram
      @hamedbahram  Před 4 měsíci

      Not really, you can change the `accept` property.

  • @angelicoctahedron3646
    @angelicoctahedron3646 Před 9 měsíci +1

    It doesn't show not-allowed cursor when dragging non-image. What can we do with that?

  • @user-nk2ol7of1l
    @user-nk2ol7of1l Před 3 měsíci

    i'm working on a project where users can purcase a mobile case before the order they have to edit the mobile back case , like they want (Adding the image , editing , rotating , resizing and adding the text) and once the editing is over they may save the image at that i have to store it in the backend using express , For the User interface im using the React , is there any NPM package to do that ??? I'm stuck in this for a week not able to figure it out.....

    • @hamedbahram
      @hamedbahram  Před 3 měsíci

      Is it for working with the image?

    • @user-nk2ol7of1l
      @user-nk2ol7of1l Před 3 měsíci

      @@hamedbahram yes full and full image editing add mulpti in the particular layout editing there

  • @mojtabaakhlaghi4029
    @mojtabaakhlaghi4029 Před 2 měsíci +1

    Hi
    could you say me the font name that you are using in your vs code please

  • @shyamksukumaran
    @shyamksukumaran Před rokem

    How can I get the actual File Type from in react-dropzone. Currently Type is extracted based on file extension however if I rename a file sample.pdf to sample.pdf.jpg, it will return type as Image/JPEG not as application/pdf.

    • @hamedbahram
      @hamedbahram  Před rokem

      Good question, you can pass a custom `validator` function that receives the `File` as the argument, do whatever validation you need to do and then decide whether or not the file is accepted or rejected.

    • @shyamksukumaran
      @shyamksukumaran Před rokem

      @@hamedbahram Thanks Hamed. However when I try to add validator ' Object literal may only specify known properties, and 'validator' does not exist in type 'DropzoneOptions'.ts.

    • @hamedbahram
      @hamedbahram  Před rokem

      @@shyamksukumaran check the docs, you should be able to add a custom validator function. Here is a link: react-dropzone.js.org/#section-custom-validation

  • @Mounika_Oka_Chinna_Kuti
    @Mounika_Oka_Chinna_Kuti Před rokem +1

    Do we have progress bar option

    • @hamedbahram
      @hamedbahram  Před rokem +1

      That can be a nice feature. I don't have it in this tutorial though.

  • @santiago97399
    @santiago97399 Před 8 měsíci +1

    Unhandled Runtime Error
    SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
    Im getting this error

    • @hamedbahram
      @hamedbahram  Před 8 měsíci

      Not sure where you're getting that! Compare your code to mine (link in the video description) and see what you're doing differently.

    • @santiago97399
      @santiago97399 Před 8 měsíci +1

      It seems i have fixed this issue, but another one popped,and trying to solve this with no result. any idea how to solve hamed?
      : Unhandled Runtime Error
      TypeError: NetworkError when attempting to fetch resource.
      Source
      components/Dropzone.jsx (61:23) @ fetch
      59 |
      60 | const URL = process.env.NEXT_PUBLIC_CLOUDINARY_URL
      > 61 | const data = await fetch(URL, {
      | ^
      62 | method: 'POST',
      63 | body: formData
      64 | }).then(res => res.json())

    • @hamedbahram
      @hamedbahram  Před 8 měsíci

      @@santiago97399 Sorry it's hard to tell what's going wrong. Again compare your code to mine :)

  • @santiago97399
    @santiago97399 Před 8 měsíci +1

    how can i do this for google cloud services since its json?

    • @hamedbahram
      @hamedbahram  Před 8 měsíci

      You can use the Google cloud storage SDK and upload your files to your bucket.

  • @GabrielMartinez-ez9ue
    @GabrielMartinez-ez9ue Před rokem +1

    Having an unsigned url is a security issue. Users can fill up your cloudinary very quickly with images.

    • @hamedbahram
      @hamedbahram  Před rokem +2

      That's right, Gabriel; using a signed preset for a production application is better. Appreciate your feedback.

    • @SanchitTewari
      @SanchitTewari Před rokem +1

      @@hamedbahram can you tell how to achieve that?

    • @hamedbahram
      @hamedbahram  Před rokem

      @@SanchitTewari Watch this video where I explaing how to use signed uploads in Cloudinary: czcams.com/video/gW7DSJ2a6pg/video.html

    • @SanchitTewari
      @SanchitTewari Před rokem

      @@hamedbahram i actually came up with an alternative...
      we can just convert it into base64 right?

  • @user-bl6fl4od2p
    @user-bl6fl4od2p Před rokem +1

    hi teacher Warning: Encountered two children with the same key. How can I fix this?

    • @hamedbahram
      @hamedbahram  Před rokem

      You need to use a unique `key` attribute for child elements inside of a list. Usually happens when you're using `map` to loop through an array of data to render a react element for each object.

  • @noname-rp8pv
    @noname-rp8pv Před 10 měsíci +1

    Hi, anyone having cors issue?

    • @hamedbahram
      @hamedbahram  Před 10 měsíci +1

      I haven't had that on my end. What error are you getting?

    • @noname-rp8pv
      @noname-rp8pv Před 10 měsíci +1

      @@hamedbahram Hi, thanks for the response.
      I have fixed that. My NEXT_PUBLIC_CLOUDINARY_URL didn't had /image/upload at the end of url. Without it, had CORS error message in console.

    • @hamedbahram
      @hamedbahram  Před 10 měsíci +1

      @@noname-rp8pv Awesome!