用一行代码进行状态管理

2025-05-24

用一行代码进行状态管理

如果您像我一样,觉得必须有一种更简单的状态管理方法,那么您会喜欢ActiveJS为您做的事情。

我感觉自己像是在推销蛇油,但在过去的 10 个月里,我一直在尝试让状态管理尽可能直观和简单,因为我无法忍受目前的状态管理。

为了实现高效的状态管理,我们需要做以下几件事

  • 类型安全的数据结构
  • 可以在突变时发出事件的数据结构
  • 可以保证不变性的数据结构
  • 可以通过会话持久化的数据结构

标题承诺用一行代码实现所有这些,所以就在这里。

const dataUnit = new DictUnit({
 id: 'data', immutable: true, persistent: true, cacheSize: Infinity,
 initialValue: {a: 1}
})
// every option is optional, including the initialValue
// DictUnit has empty object {} as it's default value
Enter fullscreen mode Exit fullscreen mode

(好吧,有 4 行,但我已将其格式化,因此您不必滚动:)

JavaScript 没有这样的东西,这就是 ActiveJS 出现的原因,并且随之出现了称为Units的反应式数据结构,其中之一就是DictUnit,它始终存储并确保字典对象的值。

您可能已经从我们传递给 DictUnit 的配置选项中有所了解,并猜到了它的全部内容,但详细说明 DictUnit 是:

  • 可观察的
  • 反应式
  • 类型安全
  • 不可变
  • 坚持不懈,并且
  • 已启用缓存

让我们用我们都理解的语言看看这是什么意思,代码如下:

可观察的

DictUnit扩展了 RxJS Observable 类,因此您可以订阅它并在其上应用所有 RxJS 操作符,就像在 Observable 上一样。

// subscribe for the value
dataUnit.subscribe(value => console.log(value))
// logs {a: 1} immediately and will log future values

dataUnit instanceof Observable; // true
Enter fullscreen mode Exit fullscreen mode

反应式

当您更新 DictUnit 的值时,它会将其发送给所有观察者,以便他们能够访问最新值。

// non-functional dispatch
dataUnit.dispatch({b: 2, c: 3})
// observers get {b: 2, c: 3}

// now dataUnit's value is {b: 2, c: 3}

// functional-dispatch
dataUnit.dispatch(value => {return {...value, d: 4}})
// observers get {b: 2, c: 3, d: 4}

// we don't have to dispatch new values manually,
// DictUnit provides a better way to update properties

// update a single property
dataUnit.set('d', 5)
// observers get {b: 2, c: 3, d: 5}

// delete properties
dataUnit.delete('b', 'd') // 'b' and 'd' got yeeted
// observers get {c: 3}

// update multiple properties
dataUnit.assign({a: 1, b: 2})
// observers get {a: 1, b: 2, c: 3}
Enter fullscreen mode Exit fullscreen mode

类型安全

DictUnit 确保值始终是一个字典对象,它将忽略任何无效的值分派。

dataUnit.dispatch(['let', 'me', 'in']); // won't work
dataUnit.dispatch('let me in'); // won't work
dataUnit.dispatch(420); // won't work
dataUnit.dispatch(null); // won't work
dataUnit.dispatch(new Date()); // won't work
dataUnit.dispatch(() => new Date()); // won't work
Enter fullscreen mode Exit fullscreen mode

与 ActiveJS 中的 DictUnit 类似,还有 5 个其他 Unit,用于存储的ListUnitarray用于存储的NumUnitnumber用于存储的StringUnitstring用于存储的BoolUnitboolean用于存储任何内容的GenericUnit 。

不可变

immutable 标志确保 DictUnit 不会让值以任何方式发生变异。无论如何,我们还是尝试改变它吧。

const newValue = {c: 3};
dataUnit.dispatch(newValue) // works, value is {c: 3} now

// try mutating the newValue
newValue.c = 'hehe' // works, but
dataUnit.value() // still {c: 3}

// let's try a different approach
const currentValue = dataUnit.value() // {c: 3}
currentValue.c = 'gotcha' // works, but
dataUnit.value() // still {c: 3}
Enter fullscreen mode Exit fullscreen mode

执着的

持久标志使 DictUnit 持久化,这样每当它的值更新时,它都会将该值保存到 LocalStorage,因此如果我们使用相同的标志重新初始化 DictUnit idpersistent: trueDictUnit 将从 LocalStorage 恢复其值。

dataUnit.dispatch({c: 4}) // saved in LocalStorage

// after refreshing the browser-tab or reinitializing the DictUnit
dataUnit.value() // {c: 4}
// it restored the value from LocalStorage
Enter fullscreen mode Exit fullscreen mode

已启用缓存

如果我告诉你,我们可以回到之前示例中更新的所有值,然后再回到当前值,那会怎么样呢?没错,时间旅行是可以实现的。你只需要指定希望使用该cacheSize选项返回多少步,默认情况下,它保留 2 个值,最多支持无限个。

// let's reinitialize the Unit to demonstrate cache-navigation
const dataUnit = new DictUnit({
 cacheSize: Infinity, initialValue: {a: 1}
})
// now let's dispatch a bunch of values to fill the cache
dataUnit.dispatch({b: 2})
dataUnit.dispatch({c: 3})
dataUnit.dispatch({d: 4})
dataUnit.dispatch({e: 5})

// now the value is {e: 5}, and
// the cache looks like this [{a: 1}, {b: 2}, {c: 3}, {d: 4}, {e: 5}]

// go back 1 step
dataUnit.goBack()
// now value is {d: 4}

// go back 2 steps
dataUnit.jump(-2) // negative means back, positive means forward
// now value is {b: 2}

// jump to the last value in cache
dataUnit.jumpToEnd()
// now value is {e: 5}

// jump to the first value in cache
dataUnit.jumpToStart()
// now value is {a: 1}

// go forward 1 step
dataUnit.goForward()
// now value is {b: 2}
Enter fullscreen mode Exit fullscreen mode

就这样,朋友们,一切都完成了。

我们还有一些 DictUnit 的功能没有讲到,比如管理异步 API 调用之类的。不过这些也许可以留到下一篇文章再讲。

与此同时,注意安全,尽量享受乐趣,并前往ActiveJS 网站文档,了解有关如何帮助您以最少的努力管理状态的更多信息。

如果您想亲自尝试一下,这里是StackBlitz 游乐场链接。

这是可视化游乐场的链接,您无需编写任何代码即可尝试。

另外,我忘了告诉你,这是我在任何平台上发表的第一篇文章,请告诉我我做得是否还好,或者是否有可以改进的地方。

干杯

🌏 ActiveJS 网站
📖 ActiveJS 文档
🤾‍♂️ ActiveJS 游乐场
💻 ActiveJS GitHub Repo(也许放个 ⭐ :)

下一篇:使用 ActiveJS 进行异步状态管理

文章来源:https://dev.to/dabalyan/state-management-with-a-single-line-of-code-2llg
PREV
100 个开发人员职位 - 冠状病毒危机期间公司仍在招聘
NEXT
使用这 4 个移动应用程序目录排序列表在您的手机📱上输入代码👨‍💻