首页 文章

为什么Redux减速机称为减速机?

提问于
浏览
26

在学习 Redux 的时候,我遇到了 Reducers . 文件说明:

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

MDN将 reduce 方法描述为:

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

我没有意义 . 其次,MDN描述似乎也不正确 . reduce 方法并不总是用于减少单个值 . 它可用于代替 mapfilter ,并且在用于代替链接时实际上更快 .

MDN描述不正确吗?

回到Redux定义的reducer,它指出:

它被称为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 将是初始值 .

谢谢你有任何明确的解释 . 这很难概念化 .

5 回答

  • 2

    术语“减少”实际上是函数式编程中使用的函数术语 . 在像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"(具有上面定义的方法签名的函数)并返回单个值 . 现在,是的,你可以用它来做其他的事情,如果你调用的函数有副作用,但你不应该 .reduce() 使用 .reduce() 作为foreach . )即使用 reduce 调用的方法有副作用,返回值也是减少本身将是一个单一的 Value ,而不是一个集合 .

    关于这一点很酷,这个模式不仅仅适用于数组或具体集合,正如你在React中看到的那样;这种模式也可以应用于流,因为它们是纯函数 .

    希望这可以帮助 . 对于它的 Value ,可以改进Redux站点上的定义(因为reducer的概念不仅仅是因为Javascript的Array原型方法) . 你应该提交公关!

    编辑:有's a Wikipedia article on the subject. Note that reduce has different names, and in functional languages, it'俗称折叠 . https://en.wikipedia.org/wiki/Fold_(higher-order_function)#Folds_as_structural_transformations

  • 7

    redux reducer被称为reducer的原因是因为你可以“减少”一组动作和一个初始状态(商店),在这个状态下执行这些动作以获得最终的状态 .

    怎么样?要回答这个问题,让我再次定义一个减速器:

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

    还有什么呢?减速机吗?

    reducer是一个纯函数,它接受当前状态和一个动作,并返回下一个状态 . 请注意,当应用集合上的每个操作来更改此状态时,将累积状态 .

    因此,给定 collection of actions ,reducer将应用于集合的每个值(从左到右) . 第一次,它返回 initial value . 现在,reducer再次应用于此初始状态,并且第一个操作将返回下一个状态 . 并且每次在 current state 上应用下一个集合项(操作)以获取 next state ,直到它到达数组的末尾 . 然后,你得到 the final state . 多么酷啊!

  • 0

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

    Array.reduce

    这与将作为回调(reducer)传递给Array.reduce的内容非常相似 . 重要的是:

    callback
      Function to execute on each value in the array, taking four arguments:
        previousValue
          The value previously returned in the last invocation of the callback, or initialValue, if supplied. (See below.)
        currentValue
          The current element being processed in the array.
    

    其中state是“previousValue”,action是“currentValue” .

  • 2

    对不起,但我不同意以前的答案 . 我 would not 支持命名 reducer . 我责备我,读第二部分,但我想先说明,为什么我不同意 .

    减速器是变换序列是正确的,但序列本身 - 可能是另一个序列的一部分 . 想象一下,就像链接一样 - 链条的一部分 . 但链条本身可能是更长链的一部分 . 每个环节都是全球国家的“过渡” . 比,它背后的理论是什么?

    Isn 't it actually the 1114607 ? - close, but not. It' s实际上是Transition system .

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

    所以, S - 是我们的状态

    Λ - 是我们所谓的"actions"(但理论上是标签)

    ......和

    - 减速机"labelled transitions"!如果我是这个库的创建者,我会这么说 .

    理解这个理论帮助我实现了我的库,我可以将 low-level transition system 作为 high-level transition system 的一部分(如链 - 仍然可以成为更长链的一部分) - 并且仍然具有单个全局Redux状态 .

  • 19

    我的印象是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将是初始值 .

    // count function from your question
    const count = function (state, action) {
        if (action.type == 'INCREMENT') {
            return state + 1;
        } else if (action.type == 'DECREMENT') {
            return state - 1;
        } else {
            return state;
        }
    }
    
    // an array of actions
    const actions =
      [ { type: 'INCREMENT' }
      , { type: 'INCREMENT' }
      , { type: 'INCREMENT' }
      , { type: 'INCREMENT' }
      , { type: 'DECREMENT' }
      ]
    
    // initial state
    const init = 0
      
    console.log(actions.reduce(count, init))
    // 3 (final state)
    // (INCREMENT 4 times, DECREMENT 1 time)
    

相关问题