首页 > 解决方案 > Redux saga:我如何确保只有我的 saga 能够更新某个状态?

问题描述

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

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

这就是我目前的做法:

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

  2. Redux Saga 举办活动。

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

  4. 为之前的 appLaunchCount 添加 +1。

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

  6. 使用新的 appLaunchCount 将 put() 发送到 reducer。

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

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

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

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

标签: react-nativereduxreact-reduxredux-saga

解决方案


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

你可以做的是让动作有一个类型,让它很明显是私有的。例如,也许动作看起来像:

{
  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,那么您可以确保其他文件无法访问此符号;但是一旦你开始出口它就变得更难控制了。


推荐阅读