react how to make a re-render for update of value in local storage

Viewed 1260

I'm trying to show a spinner with a percentage value when there is a file upload in my react application. I'm using material UI circular progress to do this. So I'll make a rest call using Axios and configure it to give me the percentage values and save them to local storage. The code for my rest call looks like:

callRestService(URL,postBody){
 const config = {
    onUploadProgress: function(progressEvent) {
    var percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total)
    console.log(percentCompleted);
    localStorage.setValue('percentage',''+percentCompleted);
   }
 }
 axios.post(URL, postBody, config)
    .then(res => console.log(res))
    .catch(err => console.log(err))
}

And the code snippet for the spinner component is

export default function CircularProgressWithLabel(props) {
  const initialPercentage = () => Number(localStorage.getItem('percentage') || 0);
  const [percent,setPercent] = React.useState(initialPercentage);
  React.useEffect(() => {
    setPercent(Number(localStorage.getItem('percentage')));
  },[localStorage.getItem('percentage')])
  return (
    <Box position="relative" display="inline-flex">
      <CircularProgress variant="static" {...props} />
      <Box
        top={0}
        left={0}
        bottom={0}
        right={0}
        position="absolute"
        display="flex"
        alignItems="center"
        justifyContent="center"
      >
        <Typography variant="caption" component="div" color="textSecondary">
          {percent}
        </Typography>
      </Box>
    </Box>
  );
}

I'm using these two helper methods in a parent component in this way:

function mainComponent(){
  ...
  const [loading,setLoading] = React.useState(false);
  ...
  // this function will be called when a button is clicked.
  async function importFile(){
    setLoading(true);
    await callRestService('endpontURl',data);
    setLoading(false);
  }

  ...

  return{
    ...

    { loading && <CircularSpinner/> }
  }
}

Now the problem is that the spinner component is being rendered only once, i.e whenever I'm setting the loading hook to true, and since the initial value for percentage in circular spinner is zero it'll not show the spinner component. But later I'm updating localStorage value in callRestService and has a useEffect that listens to localStorage value in the spinner component, I expected that the spinner component will be rendered each time the value is updated in callRestService , But that isn't happening. So could someone help me out with this, I would like to render the spinner component each time there is an update in local storage value thereby providing a way to get the latest uploaded percentage value. Or is there an alternative to provide the value returned by Axios in callRestService component to the spinner component.

1 Answers

components usually render with state change you can bind one state for local storage (if u need local storage anyway) and just update the state each time

Related