Redux 状态在窗口重新加载时重置(客户端)

IT技术 javascript reactjs redux local-storage state
2021-05-23 21:10:35

我有非常大和复杂的对象,如 userInfo、chatInfo 等,如具有非常大和嵌套信息的对象和数组。每次刷新页面时,我的react应用程序都会重置 redux 状态,我必须再次调用所有这些 API。

我对这个话题做了一些研究。我查看了 Dan Abramov 的关于 redux 的 egghead 教程。他所做的是在浏览器的 localStorage 中维护 redux 状态,并在每 100 或 500 毫秒后更新 localStorage。我觉得这好像是一种代码气味。

不断的观察localStorage的状态并更新,会不会影响浏览器的性能。我的意思是这不是 Angular 1 失败的原因,因为它持续不断地观察状态变量,一段时间后,如果站点在浏览器中保持活动状态,它只会变慢。因为我们的脚本不断地检查变量的状态。我觉得我们在这里做着同样的事情。

如果在 localStorage 中维护 redux 状态是正确的方法,有人可以告诉我为什么会这样吗?如果没有,有没有更好的方法?


这不是如何在刷新时保留 redux 状态树的副本因为我在征求意见,在本地存储中持久化状态是否是一种代码异味

4个回答

我认为使用localStorage是您最好的选择,因为客户端似乎需要您存储在那里的数据。如果数据没有变化,则不需要重复查询或观看localStorage.

您可以做的另一件事是在您的 周围包裹一个闭包localStorage,这样您在检索“大”数据时就不会总是碰到磁盘。每个浏览器的实现都localStorage不同,因此无法保证一致的行为或 I/O 性能。

这还添加了一个简单的抽象层,它隐藏了实现,并在一个地方控制与用户数据相关的所有内容。

这是用户配置文件数据关闭的简单示例:

// 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;

设置用户数据对象:这将覆盖localStorage, 并在闭包内设置局部变量。

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

获取用户数据对象:这将从闭包内部的局部变量中获取数据,否则localStorage如果未设置则从那里获取

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

这里的想法是将数据加载到内存中,从localStorage,第一次,当你的应用程序加载时,或者在第一次 API 调用时。直到用户个人资料数据发生变化(例如,用户更新他们的个人资料),然后您将再次查询 API,并通过UserProfile.setUserData(..)调用再次更新数据

问题是你需要在什么时候实现持久化。我觉得你的情况的答案是在页面重新加载上。因此,如果您担心性能,我会说: * 仅在状态更改时更新 localStorage。更新状态时在减速器内部。* 启动应用程序时从 localStorage 读取。

(这样你只在状态改变时才写,你只读一次)

PS 我会推荐https://github.com/rt2zz/redux-persist包来在 Redux 应用程序中实现持久化。

我只会把它作为一个弱缓存来做,不会依赖它。本地存储空间有限(例如 Chrome 上的 5mb),并且可能不可用。您必须仔细验证您的数据是否已写入。

正如其他人所说,您不会观看 localStorage,您会定期刷新商店。但是我同意,盲目地假设您的所有状态都适合持久保存在本地存储中似乎是一种相当粗略的技巧。与所有缓存解决方案一样,您需要仔细考虑影响(新鲜度、过期等)。听起来您可能想要逐步执行此操作 - 挑选一些适合缓存的低挂水果,并考虑在本地存储中缓存该状态的影响。

尝试redux-persis你可以做乐观的持久性,不可知底层平台(网络/移动)。

如果您仍然发现性能是瓶颈。您可以按步骤执行以下任一操作。

缓存中间件

创建一个中间件来监听更改并记录它们,但每 5 秒才刷新一次。

将事件处理程序附加到window.beforeunload以检测用户导航或关闭浏览器以刷新更改

坚持策略

要保留数据,您可以使用以下两种策略之一。

  • 如果没有性能瓶颈,则将其存储在 localStorage 中。
  • 像文件上传一样将 JSON blob 发送到服务器。当应用程序加载并在本地持久化时获取最后的 JSON 状态。

我建议您从使用redux-persist 开始如果仍然存在性能瓶颈,则使用缓存中间件以及两种持久性策略之一。