Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redux State Resets On Window Reload (Client Side)

Tags:

I have very large and complicated objects like userInfo, chatInfo, and etc as in objects & arrays with very large and nested information. The thing is in my react app every time I refresh my page the redux state gets reset and I have to call all those API's again.

I did some research on this topic. I checked Dan Abramov's egghead tutorial on redux. What he does is maintain the redux state in localStorage of the browser and updated the localStorage after every 100 or 500 ms. I feel as if this is a code smell.

Continuously watching the localStorage state and updating it, wouldn't it effect the performance of the browser. I mean wasn't this on of the reasons Angular 1 failed because it continuously kept on watching state variables and after a while if the site was kept live in the browser it just slowed down. Because our script continuously kept on checking the state of the variables. i feel as if we are doing the same thing here.

If maintaining the redux state in localStorage is the right approach can someone tell me why so? And if not is there a better approach?


This is not a duplicate of How can I persist redux state tree on refresh? because I am asking for advice whether persisting state in local storage is a code smell or not

like image 709
Adeel Imran Avatar asked Dec 26 '17 18:12

Adeel Imran


People also ask

Does Redux state reset on refresh?

When we refresh page in a web-app, the state always resets back to the initial values which in not a good thing when you try to build some large web-app like e-commerce. We can manually do the state persistent using the native JavaScript localStorage.

How do I save Redux state on page refresh?

If you would like to persist your redux state across a browser refresh, it's best to do this using redux middleware. Check out the redux-persist and redux-storage middleware. They both try to accomplish the same task of storing your redux state so that it may be saved and loaded at will.

How do you prevent state change in React after page refresh?

To maintain state after a page refresh in React, we can save the state in session storage. const Comp = () => { const [count, setCount] = useState(1); useEffect(() => { setCount(JSON.

What happens when Redux state changes?

The fact that the Redux state changes predictably opens up a lot of debugging possibilities. For example, using time travel makes it possible to travel back and forth between different states instead of having to reload the whole app in order to get back to the same place.


2 Answers

I think using localStorage is your best option here, since it seems the data you are storing there is needed on the client. If the data is not changing, you shouldn't need to repeatedly query, or watch, the localStorage.

Another thing you can do is wrap a closure around your localStorage, so that you are not always hitting disk when retrieving your "large" data. Every browser implements localStorage differently, so there are no guarantees on consistent behaviour or I/O performance.

This also adds a simple layer of abstraction which hides the implementation, and controls everything related to your user data in one place.

Here is a simple example of user profile data closure:

// UserProfile.js
var UserProfile = (function() {
  var userData = {};

  var getUserData = function() {
    if (!userData) { 
      userData = JSON.parse(localStorage.getItem("userData"));
    }
    return userData;
  };

  var setUserData = function(userData) {
    localStorage.setItem("userData", JSON.stringify(userData));
    userData = JSON.parse(localStorage.getItem("userData"));
  };

  return {
    getUserData: getUserData,
    setUserData: setUserData
  }
})();

export default UserProfile;

Set the user data object: This will overwrite the localStorage, and set the local variable inside the closure.

import UserProfile from '/UserProfile';
UserProfile.setUserData(newUserData);

Get the user data object: This will get the data from the local variable inside the closure, or else go get it from localStorage if it is not set.

import UserProfile from '/UserProfile';
var userData = UserProfile.getUserData();

The idea here is to load data into memory, from localStorage, the first time, when your app loads, or on the first API call. Until such a time when the user profile data changes, (i.e. a user updates their profile, for example), then you would query the API again, and update the data again via the UserProfile.setUserData(..) call.

like image 109
grizzthedj Avatar answered Oct 08 '22 01:10

grizzthedj


The question is at what point you need to achieve persistent. I feel that the answer in your case is on a page reload. So if you are worry about performance I'll say: * Update the localStorage only when the state changes. Inside your reducer when you update the state. * Read from localStorage when you boot the app.

(This way you write only when the state changes and you read only once)

P.S. I'll recommend https://github.com/rt2zz/redux-persist package for achieving persistent in Redux apps.

like image 31
Krasimir Avatar answered Oct 08 '22 02:10

Krasimir