为什么Redux需要动作和简化器?

时间:2018-08-13 21:06:17

标签: javascript reactjs typescript redux

我试图理解为什么Redux是按原样设计的。例如,假设我有一家商店,里面有待办事项清单。

如果商店实际上是这样的对象:

{1: todo1,
 2: todo2,
 3: todo3, ...}*

然后将其包装在一个类中,该类允许我们执行以下操作:

todoStore.getAll()
todoStore.add(todo)
todoStore.get(id);
todoStore.get([1,2,3,...]);
todoStore.filter((todo)=> todo.id == 1);
todoStore.del(1);
todoStore.update(2, {title: 'new title'}:Partial<Todo>);
....

因此,在这种情况下,我们只拥有一个Todo模型和一个TodoStore,该模型具有一个API,可以让我们查询/过滤,删除,更新和添加项目。

为什么Redux需要Actions和Reducer?

答案之一表明:

  

相反,Redux使用一种模式,当给定状态和动作时,它将始终产生相同的新状态。

因此,由于这种模式,我们似乎需要动作和减速器,但对我而言,它们看起来像是内部实现的细节。 TodoStore为什么不能仅在内部实现这些功能?

例如,如果我们在缓存中有1个todo实例,而我们又添加了一个,则现在有了2个。这似乎很容易实现……但是我一定会遗漏一些东西……

背景

我当时正在考虑实施类似的

@TodoStore
class Todo {

}

注释/装饰器将生成商店,然后客户将通过以下方式获得商店:

todoStore:TodoStore = StoreCache.get(Todo);
todos:Observable<Todo[]> = todoStore.getAll();
...

等等看起来可能就这么简单...所以只是想知道Redux提供的内容可能会丢失...换句话说,为什么redux决定它需要操作和reducer而不是像Store<Type>这样的简单界面?

看待它的另一种方式是,Reducers and Action是否添加了Store<Type>接口无法通过实现方式/语言约束添加的内容?

断言

  • 操作是方法名称和实体名称的组合。因此,例如,如果我们有Store<Todo>(一种对待办事项类型进行操作的商店类型),并且说一种更新方法(例如update(id:String, todo:Todo)),那么我们有效地将Action的名称命名为待办事项更新。如果第二个参数为复数,则update(id:String, todos:Todo[]) TODO UPDATES ...

  • 如果要进行更新,则必须找到要更新的实例并对其进行更新,并且通常使用ID来执行。更新完成后,如果我们愿意的话,我们可以在不可变的状态树中跟踪它们,例如,可以将整个更改包装在命令对象实例中,以便我们撤消/重播它。我相信Eclipe EMF框架API为此提供了一个很好的模型,并为生成的模型提供了Elipse撤消/重做功能。

2 个答案:

答案 0 :(得分:3)

这个问题似乎有点广泛或基于观点,但我会试一试。

Redux存储是不可变的,因此不能更改存储。相反,Redux使用一种模式,当给定状态和动作时,它将始终产生相同的新状态。这些动作是准确的,告诉商店要执行什么动作,然后减速器执行该更改并返回新状态。

如果您来自可变的面向对象的背景,这可能会觉得很奇怪,但是它使您可以浏览状态更改,追溯历史并重播动作等。这是一个强大的模式。

答案 1 :(得分:1)

对于评论来说,这太长了,可能是一个答案,但这更多是关于Redux存在的概念,而不是其实现的具体细节。

考虑看似简单的赋值语句:

var foo = {bar: 1};
foo.bar = 3;

简单吧?除非...如果我需要先前的foo.bar值怎么办?如果我需要存储对状态转换本身的引用怎么办,例如重新播放吗?语句不是JavaScript中的一流实体:

var transition = foo.bar = 3;

不是很有意义。您可以将其包装为lambda表达式:

var transition = () => { foo.bar = 3 };

但是,这无法捕获过渡语义,只是将foo.bar的状态设置为3。如果前一个状态对下一个状态很重要,该怎么办?您如何分享foo?将其填充到全局中,并希望没人对您进行变异吗?但是,如果foo周围的语义很清晰,则状态会发生变化,否则是不可变的,那么...

有些有用的属性不在此范围内

  1. 代码重装。如果所有状态更改都是一流的,则可以重新加载代码,然后只需重播即可回到原来的状态。
  2. 在服务器上复制。如果生产错误转储了创建错误的状态转换怎么办?曾经无法复制错误吗?过去的事。
  3. 撤消很简单。

还有其他人,但是您明白了。现在,您可能并不需要所有这些,也可能不值得失去灵活性(以及Redux would agree的作者Dan Abramov)。但是,通过在系统中提供状态转换为一流的状态,可以获得很多好处。

相关问题