React store API response in localStorage

Viewed 39

I have an API that returns a list which is shown as a grid in my main component. I store the list in localStorage bcz I don't want that API to be called every time the component is rendered. It looks something like this:

const setOldData = (dataRN) => {
    console.log("Using old data...")
    setContent(JSON.parse(dataRN));
    let tmpArr = JSON.parse(dataRN).CodeList;
    setData(JSON.parse(dataRN).RNList);
    var tmp = groupBy(tmpArr, 'groupname');
    setAktNaloga(tmp.GetListaAktivnostNaloga);
    setTipAkcije(tmp.GetListaVrstaAkcijeNaloga);
    setKorGrupa(tmp.GetListaKorisnickihGrupa);
    setLinijaProdukta(tmp.GetListaLinijeProdukataNaloga);
    setPrioritet(tmp.GetListaPrioritetNaloga);
    setStanje(tmp.GetListaStanjeNaloga);
    setStatus(tmp.GetListaStatusaNaloga);
    setLokacija(tmp.GetListaPodrucjeOdrzavanja);
  }


useEffect(() => {
    showLoader();
    console.log("Getting srv data");

    window.addEventListener('resize', handleResize);


    let unmounted = false;
    let source = axios.CancelToken.source();

    let datestring = dateStart.getDate() + "." + (dateStart.getMonth() + 1) + "." + dateStart.getFullYear();

    console.log(datestring);

    setDateStartSend(datestring);

    let datestringEnd = dateEnd.getDate() + "." + (dateEnd.getMonth() + 1) + "." + dateEnd.getFullYear();

    console.log(datestringEnd);

    setDateEndSend(datestringEnd);

    if (window.localStorage !== undefined) {
      const dataRN = window.localStorage.getItem('rnList');
      dataRN !== null ? setOldData(dataRN) :   RNService.getRNList(source.token, datestring, datestringEnd, currentUser.userName).then(
        (response) => {
  
          if (!unmounted) {
  
            localStorage.setItem('rnList', JSON.stringify(response.data));

            setContent(response.data);
  
            console.log('getRNLista', response.data);
  
            let tmpArr = response.data.CodeList;
  
            setData(response.data.RNList);
  
  
            var tmp = groupBy(tmpArr, 'groupname');
  
            console.log("Statusi; ");
            console.log(tmp.GetListaStatusaNaloga);
  
            setTipZahtjeva(tmp.GetListaVrstaZahtjeva);
  
            console.log(tmp.GetListaVrstaZahtjeva);
            console.log("AAA");
            setAktNaloga(tmp.GetListaAktivnostNaloga);
            setTipAkcije(tmp.GetListaVrstaAkcijeNaloga);
            setKorGrupa(tmp.GetListaKorisnickihGrupa);
            setLinijaProdukta(tmp.GetListaLinijeProdukataNaloga);
            setPrioritet(tmp.GetListaPrioritetNaloga);
            setStanje(tmp.GetListaStanjeNaloga);
            setStatus(tmp.GetListaStatusaNaloga);
            setLokacija(tmp.GetListaPodrucjeOdrzavanja);
  
  
  
  
  
            console.log("Count: " + response.data.RNList.length);
            hideLoader();
          }
  
  
        },
  
        (error) => {
  
          if (!unmounted) {
            console.log("Error rq");
  
            console.log(error.response.status);
  
            if (error.response.status == 401) {
  
              alert(error.response.data.message)
  
              window.localStorage.removeItem('rnList')

              logOut();
  
            } else {
  
              //alert(error.response.data.message)
              alert("Problem");
            }
          }
  
  
        }
  
  
      );
    }

   hideLoader();

  }, [reload]);

So, in useEffect it is checked if there is something in localStorage, if there is --> don't call the API; if there isn't --> call the API. Also, my login token lasts for an hour, so if you logged in now, in an hour, if you are in this component, useEffect would throw an error and kick you out for you to login again.

BUT, here comes the problem --> the error can't be thrown bcz once I filled up localStorage, I don't know how to empty it properly, or, what I want to say, I don't know WHERE exactly should I empty it.

I want to empty it once the token has ran out, but I don't know the best possible solution for it. Should I make an API that just checks the token validity and put it in setOldData method and, if it has ran out, throw an error, kick the user out and clear the localStorage?

Or, should I use sessionStorage, Redux...?

1 Answers
const currentTime = Date.now() / 1000; // to get in milliseconds
      if (decoded.exp < currentTime) {
        // Logout user
        store.dispatch(logoutUser());
    
        // Redirect to login
        window.location.href = "./sign-in";
      }

You may use Redux to manage the state of the application and like the above example you may check the expiration time and log out the user and clear the loaclstoreage

//Authaction.js -- redux
    localStorage.removeItem("your-item");
Related