3

I have a component to upload a video and I am trying to show the progress bar. Here is my core code.

const Upload = () => {
  const [percent, setPercent] = useState(0);
  console.log(percent); // This logs uploaded percentage every time progListener callback is called. From 0 to 100.
  const dropAccepted = async () => {
    const params = {...} // parameters to upload video like filename, file
    await APIs.uploadVideo(params, progListener);
  }
  const progListener = (event) => {
    var p = Math.round((event.loaded * 100) / event.total)
    // console.log(p) logs uploaded percentage from 0 to 100
    setPercent(p);
  }

  return (
    <h6>{percent}</h6>  
    <Dropzone onDropAccepted={dropAccepted}/>
  )
}

On progListener callback, I have updated the percent with setPercent function so I think h6 should print uploaded percentage. But it always 0. What's wrong on my code? I would appreciate any help.

daniels
  • 47
  • 1
  • 7

1 Answers1

4

Update it with useRef,

The reason why useState doesnt show the latest value is because useState is asynchronous. So in your case useState is being updated without giving it a chance to re-render. In these cases useRef plays a better role.

import React, {useRef} from "react";

const Upload = () => {
  const percent = useRef(0);

  const progListener = (event) => {
      percent.current = Math.round((event.loaded * 100) / event.total)
  }

  return (
    <h6>{percent.current}</h6>  
    <Dropzone onDropAccepted={dropAccepted}/>
  )
}
Thanveer Shah
  • 3,250
  • 2
  • 15
  • 31
  • 1
    Thanks, @Thanveer. This works like a charm. Btw, can you plz explain me what's wrong on my code? Why my code not working? – daniels Mar 17 '21 at 12:14
  • I have updated my answer, Please accept the answer and give an upvote. this will show others that is a working solution . :) – Thanveer Shah Mar 17 '21 at 12:39
  • Yes. I will accept your answer. Btw, in my understanding, after **setPercent** is called, it re-render the component. And actually, after **setPercent** is called, **console.log(percent);** is called and logged the updated percent. It doesn't mean component is re-rendered? – daniels Mar 17 '21 at 14:17