如何在没有 Redux 的情况下将状态保存在本地存储 React 中?

Posted

技术标签:

【中文标题】如何在没有 Redux 的情况下将状态保存在本地存储 React 中?【英文标题】:How do I persist state in local storage React without Redux? 【发布时间】:2018-03-05 11:26:56 【问题描述】:

我正在 React 中构建一个连接到 Firebase 的网络应用程序,该应用程序对用户进行身份验证并存储发布数据。网上似乎有很多关于使用 Redux 的文档,但是没有很多关于没有它的持久状态的文档。

当用户刷新页面时,<App /> 的状态被重置,因此我需要保留现有状态/从 Firebase 中检索它。一些文章建议使用本地存储来存储状态。但是考虑到最佳实践,应该在本地存储中存储什么?我的应用程序将所有状态存储在 <App /> 中,并将所需状态作为道具传递给相关组件。

以下两个示例假设用户已经通过身份验证并且刚刚刷新了他们的页面。我们希望保留他们的会话,我们也希望:

示例 #1:

应用程序加载并检查本地存储以查找最后存储的本地状态的字符串化对象。将状态设置为该状态或空状态。 如果检索并设置了'state',请使用this.state['uid'] 与 Firebase 同步状态(获取),然后再次更新本地存储状态。 每当用户更新某些内容时,更新状态(更新 Firebase)并更新本地存储状态。 用户注销时,清空本地存储'state'项。

示例 #2:

应用加载并检查本地存储中的 uid(在身份验证期间设置),如果找到,则使用该 uid 与 firebase 同步状态(获取)。 如果用户重新加载页面,则会再次从 Firebase 获取数据。 用户注销时,清空本地存储'uid'项。

对于第一个示例,我有效地保留了两个状态副本。一个在 React 的 State 中,另一个在浏览器的本地存储中。如果用户关闭窗口或刷新页面。

我的问题是:最佳做法是什么?

或者,是否正在构建一个需要在不同路径上持久保存用户和状态的 React 应用程序,而 Redux 完全不傻?

如果没有 Redux,学习 React 就够了,所以我想看看如果没有它,我是否可以应付。

【问题讨论】:

【参考方案1】:

在您的用例中,redux 不会帮助您,因为当用户刷新页面时,redux 的状态也会重置。如果您想在刷新/浏览器终止时保持应用的状态,则需要使用 localStorage/sessionStorage/cookies 等。

哪种方法最好?

嗯,我会说第二种方法更好。我会避免将状态副本保存在本地存储中。我只会保留某种令牌/ID(在您的情况下为uid),它唯一地标识用户并且每次都会获取新数据。当您的应用程序增长时,可能很难在本地存储中管理这些状态。

【讨论】:

firebase 设置持久性如何在本地工作。我已经从文档中实现了相同的功能,但是页面刷新后会话仍然丢失firebase.auth().setPersistence(firebase.auth.Auth.Persistence.LOCAL)【参考方案2】:

我正在使用库 Master-hook,它在没有 Redux 的情况下使用全局状态非常简单:

然后你创建“src/hooks.js”文件:

import MasterHook from 'master-hook'

export const useMyHook = MasterHook(
  storage: "myStorage",
  initialState: 
    myName: 'Vanda',
  ,
  cache: 
    myName: 10000,
  
)

您设置初始状态 (initialState:...) 设置值需要在 ms 中保持缓存多长时间 (cache:...)。当您将值放入 initialState 并将其生命周期放入以 ms 为单位的值时,计时器就会启动。即使您重新加载页面 - 该值将保存在全局状态并且您不必使用 Redux,react-redux、redux-thunk、reselect 已经安装在库 Master-hook 中。

更多Master-hook的使用方法可以找here

【讨论】:

以上是关于如何在没有 Redux 的情况下将状态保存在本地存储 React 中?的主要内容,如果未能解决你的问题,请参考以下文章

在没有用户登录 react.js 和 redux 的情况下将商品添加到购物车

如何在同一个反应组件中使用本地状态和 redux 存储状态?

如何在没有 Geofire 的情况下将位置对象保存在 Firebase 中?

Redux 路由器 - 刷新后如何重播状态?

如何在没有时间的情况下将 LocalDate 保存到 MongoDB(即使我只保存日期,为啥 mongo 会随时间保存日期)?

如何在没有本地存储的情况下将 JWT 令牌存储在 VueX 中