不可变数据助手
Redux是一个微型的模式,将状态表示为不可变的对象。 Redux最初是为React设计的。 大多数Redux概念(例如纯函数)都围绕React生态系统。 如今,Redux与React没有直接关系。
Redux的基石是不变性。 不变性是一种惊人的模式,可以最大程度地减少代码中不可预测的行为。 本文将不讨论函数式编程。 但是,我们将研究非常有用的称为"不可变数据助手"(immutability helpers)的软件包。
问题
大多数开发人员必须处理所谓的“深层对象”,最重要的是要遵循不变性概念,以更改某些深层嵌套属性的值。 给出以下代码:
export interface Task {
title: string;
dates: {
startDate: string;
dueDate: string;
};
}
export interface TrelloStateModel {
tasks: {
[taskId: string]: Task;
};
}
@State<TrelloStateModel>({
name: 'trello',
defaults: {
tasks: {}
}
})
@Injectable()
export class TrelloState {}让我们想象一下,我们有一个需要更改 dueDate 属性的需求:
让我们看看如何实现 updateDueDate 动作处理程序:
该代码可以工作,但不幸的是,维护和理解起来很复杂。 它不是自我描述的,对于新开发人员来说将是艰巨的。
解决方案
有多种方法可以改进此代码。 让我们看一些可以在这方面有所帮助的软件包。
状态操作符(State Operators)
状态操作符是NGXS提供的的一流的不可变数据助手,它开箱即用。如果选择状态运算符作为您的不可变数据助手,那么 patch 运算符将成为您最好的朋友。 让我们看看如何在patch 状态运算符的帮助下重新编写以上代码:
immer
immer 是一个非常流行的库,它使您可以对不可变对象进行更改,就好像它们是可变的一样。 以下代码显示了如何在Immer的帮助下编写相同的代码:
Immer的 produce 函数也可以用作状态运算符:
在immer库中,您可能关注这会减少多少代码,看起来有多好 :
使用Immer就像有个私人助理; 他拿了一封信(当前状态),并给了您一份副本(草稿) 来记录更改。 完成后,助手将使用你的草稿生成真正的不可变对像,即最后的封信 (下一个状态)。
immutability-helper
immutability-helper 是一个很小的包,可让您更改数据副本而无需更改原始源:
object-path-immutable
object-path-immutable 是一个小型库,可让您修改深层对象属性而不用修改原始对象。 让我们看看如何使用该库编写相同的代码:
immutable-assign
immutable-assign 是追求相同目标的轻量级库。 它的语法类似于 immer:
Ramda
Ramda 是用于函数式编程的出色库,并且已在许多项目中使用。 对于在项目中同时使用Ramda和NGXS的人,此示例可能很有用:
icepick
icepick 是用于不可变集合的零依赖库。 以下是重写后的代码:
总结
我们研究了几种不同的库,它们可能有助于伴随不可变数据的概念。 你只需要选择一个适合您需求的。
Last updated
Was this helpful?