daniels
daniels

Reputation: 47

useState not re-rendering component if it is called inside callback function

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.

Upvotes: 3

Views: 1970

Answers (1)

Thanveer Shah
Thanveer Shah

Reputation: 3333

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}/>
  )
}

Upvotes: 4

Related Questions