Crw减速机:为什么Redux减速机叫减速机(what is a reducer in react)

在学习Redux时,我遇到了Reducers。文档指出:

reducer 是一个纯函数,它接受前一个状态和一个操作,并返回下一个状态。(previousState,action) = & gt;newState。它被称为 reducer,因为它是您将传递给 Array.prototype.reduce (reducer,?initialValue) 的函数类型。

MDN 将reduce方法描述为:

reduce () 方法对累加器和数组的每个值(从左到右)应用一个函数,以将其减少到单个值。

reduce方法并不总是用于减少单个值。它可以代替mapfilter使用,当代替链接使用时,它实际上更快。

MDN 描述不正确吗?

跳回到减速器的 Redux 定义,它指出:

它被称为 reducer,因为它是您将传递给 Array.prototype.reduce(reducer,?initialValue)的函数类型

我的印象是 Redux 中的一个 reducer 负责修改状态。

const count = function(state, action) {
    if(action.type == 'INCREMENT') {
        return state + 1;
    } else if(action.type == 'DECREMENT') {
        return state - 1;
    } else {
        return state;
    }
}

...我不明白这是一个如何传递给reduce的函数。如何将数据减少到一个值?如果这是一个函数,你将传递给reduce,那么state将是回调,action将是初始值。

感谢任何明确的解释。这很难概念化。

72

术语“reduce”实际上是函数式编程中使用的函数术语,在 Haskell,F # 甚至 JavaScript 等语言中,我们定义了一个转换,该转换将(任何大小的)集合作为输入,并返回单个值作为输出。

所以(不要迂腐,但我发现这有助于我)从视觉上思考它。我们有一个集合:

[][][][][][][][][][]

...我们想要折叠成一个值:

N

在功能上进行编程,我们将使用一个函数来做到这一点,我们可以在集合的每个元素上递归调用。但是如果你这样做,你需要跟踪某个地方的中间值,对吗?非纯实现可能会在函数之外保留某种“累加器”或变量来跟踪状态,如下所示:

var accumulator = 0;
var myArray = [1,2,3,4,5];
myArray.reduce(function (each) {
    accumulator += 0;
});
return accumulator;

但是,对于纯函数,我们不能这样做-因为根据定义,纯函数不能在其函数范围之外产生影响。我们不依赖于在调用之间封装我们的“状态”的外部变量,而是简单地在方法中传递状态:

var myArray = [1,2,3,4,5];
return myArray.reduce(function (accumulator, each) {
    return accumulator + each;
}, 0);

在这种情况下,由于其方法签名,我们将函数称为“reducer”。我们有each(或current-任何名称都可以),表示集合中的对象;和state(或previous),它传递给函数的每次迭代,表示我们已经对集合中的先前元素进行的转换的结果。

请注意,您引用的 MDN 文档是正确的;reduce()函数本身总是返回一个值。实际上,任何语言中的reduce方法都是一个higher-order function,它接受一个“reducer”(具有上面定义的方法签名的函数)并返回一个值。现在,是的,您可以用它做其他事情

很酷的事情是,这种模式不只适用于数组或具体集合,正如你在 React 中看到的;这种模式也可以应用于流,因为它们是纯函数。

希望这有帮助。对于它的价值,Redux 网站上的定义可以改进 (因为 reducer 的概念不仅仅是因为 Javascript 的 Array 原型方法)。你应该提交一个 PR!

编辑:有一篇关于这个主题的文章。请注意,reduce 有不同的名称,在函数式语言中,它通常被称为 Fold。https://en..org/wiki/Fold_(higher-order_function)#Folds_as_structural_transformations

编辑(2020-10-03):人们似乎仍然发现这个有用的-这很好。随着时间的推移,我意识到“折叠”是一个更好的术语;函数式语言得到了它的权利。

23

之所以将redux reducer称为reducer,是因为您可以“减少”对其执行这些操作以获得结果final statecollection of actionsinitial state(商店)。

如何?为了回答这个问题,让我再次定义一个减速器:

reduce()方法对accumulator和数组的每个值(从左到右)应用function (reducer)以将其减少为单个值。

redux 减速器有什么作用?

reducer 是一个纯function,它接受当前状态和一个操作,并返回下一个状态。请注意,状态是accumulated,因为集合上的每个操作都用于更改此状态。

所以给定一个collection of actions,reducer 应用于集合的每个值 (从左到右)。第一次,它返回initial value。现在 reducer 再次应用于这个初始状态和第一个操作以返回下一个状态。而下一个集合项 (action) 每次都应用于current state以获得next state的数组如何结束!

14

对不起,但我不同意以前的答案。我不会支持命名reducer。我对 FP 和不变性充满热情。不要怪我,阅读第二部分,但我想先说明一下,为什么我不同意。

这是正确的,化简是变换的序列,但序列本身-可能是另一个序列的一部分。想象一下,像链接-链的一部分。但是链本身可能是更长的链的一部分。每个链接都是全局状态的“过渡”。比,它背后的理论是什么?

它实际上不是“有限状态机”吗?-close,但不是。它实际上是Transition system

带标签的过渡系统是一个元组(S,Λ,→),其中 S 是一组状态,Λ 是一组标签,并且 → 是一组带标签的过渡

所以,S-是我们的状态集

Λ-是我们所谓的“动作”(但理论上是标签

...and

-reducers“标记的转换”!如果我是这个库的创建者,我会这样命名它。

理解这个理论帮助我实现了我的库,在那里我可以有低级转换系统作为高级转换系统的一部分(像链-仍然可以是更长链的一部分)-并且仍然具有单个全局 Redux 状态。

9

调用 Redux reducersreducers在语义上是不正确的,并且没有太大意义,这就是作者感到困惑的原因。

reducer 是一个函数,它将一组值减少为一个值
我们也可以说它折叠值-因此是函数式编程中的经典fold()fn。

由于 Redux reducer和 commonator不会像它一样折叠一组值,而是将一个动作应用于一个状态,并始终返回相同的形状(State -> Action -> State)-它应该被称为applicatorapplicier
但是,由于我们必须始终返回相同的形状,因此我们

但是 Redux 听起来比AppluxMutux更酷:)

本站系公益性非盈利分享网址,本文来自用户投稿,不代表边看边学立场,如若转载,请注明出处

(270)
户户通怎么安装调试:小波作为带通还是高通 (high band pass filter)
下一篇

相关推荐

发表评论

登录 后才能评论

评论列表(19条)