Redux saga:我如何确保只有我的 saga 能够更新某个状态?

Posted

技术标签:

【中文标题】Redux saga:我如何确保只有我的 saga 能够更新某个状态?【英文标题】:Redux saga: How can i make sure only my saga is able to update a certain state? 【发布时间】:2020-01-07 20:45:03 【问题描述】:

我有一个用 React Native 制作的移动应用程序,我刚刚遇到了一个在使用 Redux/Redux Saga 时多次遇到的最佳实践困境。如果我能得到别人对此的想法,我会很高兴。

对于我正在实施的一项新功能,我需要能够知道应用程序已启动了多少次。这涉及异步检索应用程序先前从设备存储启动的次数。如果有新的发布,我还需要在号码上加上 +1 并将其存储在设备存储中。

这是我目前的做法:

    在应用启动时调度 appLaunched() 操作。

    Redux Saga 发生事件。

    Inside Saga:从设备存储中检索应用程序之前启动的次数 (appLaunchCount)(等待异步完成)。

    为之前的 appLaunchCount 添加 +1。

    在设备存储中存储新的 appLaunchCount(等待异步完成)。

    将新 appLaunchCount 的 put() 发送到 reducer。

    使用 reducer 内的新 appLaunchCount 更新状态。

我对这种方法的问题是第 6 步。从技术上讲,我的应用程序的任何部分都可以向我的减速器发送一个新的应用程序启动计数,使用任何整数,并且减速器会更新相同的状态,即使它没有出现来自传奇。

我的问题是:如何保护我的 Reducers/Sagas/Actions,以便只有我的 saga 可以使用当前 appLaunchCount 调度操作?

P.S 我能想到的唯一解决方案是将我的 saga 和 reducer 写在同一个文件中,并使用只有 saga 和 reducer 才能访问的私有操作。不过,我真的很讨厌将所有这些代码放在一起。

【问题讨论】:

【参考方案1】:

私人行动并不是真正的事情。按照设计,商店是一个全局对象。而且由于动作只是具有类型属性的对象,因此任何可以构造正确类型的动作对象的人原则上都可以调度一个动作并启动您的减速器。

你可以做的是让动作有一个类型,让它明显是私有的。例如,动作可能如下所示:


  type: '__PRIVATE_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED__'
  // You could tone it down a bit from this :)

这当然不会让它真正成为私有的,但至少如果有人想使用它,他们不可能不意识到你的意图。

如果您想让它更安全,也许您可​​以使用符号作为类型,因此只有有权访问该符号的任何人才能构造正确的操作。例如:

const appLaunchCount = Symbol('appLaunchCount');

// action would look like:

  type: appLaunchCount

但是问题在于确保该符号保持隐藏状态,并且只能由您想要访问它的人访问。与您提到的一件事类似,如果您在同一个文件中有 saga/reducer,那么您可以确保其他文件无法访问此符号;但是一旦你开始导出它就变得更难控制了。

【讨论】:

以上是关于Redux saga:我如何确保只有我的 saga 能够更新某个状态?的主要内容,如果未能解决你的问题,请参考以下文章

如何设置 redux-sagas 和文件结构?

redux saga 选择器,如何从 saga 访问状态?

如何防止 redux-saga 调用我的 api 调用两次?

如何将 redux-saga 添加到我的 Web 扩展中?

多个 redux-sagas

如何使用 Redux-Saga 和 Hooks 调用 API