Reduxの状態関数がレデューサーと呼ばれるのはなぜですか?


82

これは公式のReduxドキュメントの一部です:

これは、渡す関数のタイプであるため、レデューサーと呼ばれます。 Array.prototype.reduce(reducer, ?initialValue)

それは私にはあまり意味がありません。なぜ彼らが実際にレデューサーと呼ばれるのか誰かが私に説明できますか?それらがデフォルト値を返す(またはデフォルトの引数値を持っている)という事実は、それらをレデューサーIMHOにしません。


6
これらはreduce、デフォルト値と別の値にアクセスできる、渡した関数のように動作し、変換される可能性のあるデフォルト値を返すため、まさにレデューサーです。state -> action -> state
azium 2015

2
他の名前のバラ...おそらくマーケティング; マップ/削減今流行語です...
dandavis

1
そのため、自分で考え始め、フレームワークに依存しないようにする必要があります。フレームワークは主に、インターネットユーザーによって適応された問題を解決する方法を独自のビジョンを持つ1人または数人の開発者の作業です。いくつかのフレームワークはそれを正しくしましたが、ほとんどはそうではありません。キスの吹雪、同じかそれ以下は解決策ではありません。これは、そこにある多くの例にすぎません。
コードビート2018

回答:


71

それらがデフォルト値を返す(またはデフォルトの引数値を持っている)という事実は、それらをレデューサーIMHOにしません。

レデューサーはデフォルト値を返すだけではありません。それらは常に状態の累積を返します(以前および現在のすべてのアクションに基づいて)。

したがって、それらは状態のリデューサーとして機能します。reduxレデューサーが呼び出されるたびに、アクションとともに状態が渡され(state, action)ます。次に、この状態はアクションに基づいて削減(または累積)され、次の状態が返されます。これは、クラシックfoldまたはreduce機能の1サイクルです。

@aziumがstate -> action -> state。と要約されたように。


7
この論理によるうーん、それらはリデューサーではなくインクリザーと呼ばれるべきではありませんか?追加されるデータが削減されることはありません:/ lol
Jamie Hutber 2016年

16
@JamieHutberこの文脈でのレデューサーの意味を少し見逃していると思います。レデューサーは、アイテムのストリーム(またはコレクション)を取得し、それらを1つのアイテムに結合します。この場合、すべてのアクション(時間の経過)はアイテムのコレクションであり、状態は単一のアイテムです。意味がありますか?
Davin Tryon 2016年

7
笑今見えます。つまり、基本的にはそれらを連結するだけです。それなら合併と呼んでみませんか:P私にそれを明確にしてくれて
ありがとう

20
私がこれを書いている時点で、名前リデューサーがこの投稿で少なくとも2,000回の視聴回数から少しずれていると思うのは、私だけではありません。誰かがそれがレデューサーと呼ばれる理由を掘り起こす努力をスピンアップすることさえ喜んでいるという事実は、それが実際に少しずれていることを意味しませんか?Array.prototype.reduceに渡す関数のタイプであるためにレデューサーと呼ばれる場合、object.prototype.juicerにオレンジを渡すためにオレンジをジューサーと呼びましょう。それともフルーツと呼ぶべきではありませんか?
yini 2017年

2
私は同意します、それはまったく直感的な名前ではありません。論理的には、レデューサーと呼ばれるには、何かを減らす必要があります。状態変化の配列全体を状態と一緒に取り、それらを一度に1つの状態に結合した場合、それは直感的な名前になります。
Peter Evan Deal

20

アプリ内の一連のアクションをリストのようなもの、またはストリームのようなものと見なす場合は、より理にかなっている可能性があります。

この不自然な例を見てください:

['apple', 'banana', 'cherry'].reduce((acc, item) => acc + item.length, 0)

最初の引数は、の形式の関数です(Int, String) => Int。初期値とともにreduce、「リデューサー関数」と呼ばれるものを渡すと、一連のアイテムを処理した結果が得られます。つまり、レデューサー関数は、結果を変更するために連続する個々のアイテムで何が行われるかを記述していると言うかもしれません。つまり、レデューサー関数は前の出力と次の値を取得し、次の出力を計算します。

これは、Reduxレデューサーが行うことと類似しています。つまり、前の状態と現在のアクションを取得し、次の状態を計算します。

真の関数型プログラミングスタイルでは、引数と結果に適用される意味を概念的に消去し、入力と出力の「形状」に焦点を合わせることができます。

実際には、Reduxレデューサーは通常、特定のアクションに対してすべてが同じプロパティに変更を加えるわけではないという意味で直交しています。これにより、責任を分割し、出力をで簡単に集約できますcombineReducers


はい、その通りです。ストリームのようなアクションについて考えると、より理にかなっています。かっこいい、それを前もって!
アントンサフチェンコ

これは私が最初にそれを理解した方法でしたが、これまでに見たどのストア実装もそれを実装した方法ではないようです...
Boris Callens 2017

16

すでに述べたように、この名前は関数型プログラミングのレデューサーの概念に関連しています。また、レデューサーのMerriam-Webster辞書の定義が役立つ場合があります。

1a。一緒に描くか、収束させる:統合する(すべての質問を1つに減らす)

レデューサーは、アクションをアプリケーションの状態を表す単一のオブジェクトに統合します。


8

reduxレデューサーがaと呼ばれる理由は、これらのアクションを実行して結果を取得するreduceracollection of actionsinitial state(ストアの)を「削減」できるためですfinal state

どうやって?これに答えるために、レデューサーをもう一度定義しましょう。

低減()メソッドが適用function (reducer)に対してaccumulator、アレイの各値(左から右へ)は、単一の値に低減します。

そして、reduxレデューサーは何をしますか?

レデューサーはfunction、現在の状態とアクションを取り、次の状態を返す純粋なものです。状態はaccumulated、コレクションの各アクションがこの状態を変更するために適用されるときのものであることに注意してください。

したがって、が与えられるcollection of actionsと、レデューサーはコレクションの各値に(左から右に)適用されます。初めて、それはを返しますinitial value。これで、この初期状態と次の状態に戻る最初のアクションにレデューサーが再度適用されます。そして、次のコレクション項目(アクション)が毎回適用され、配列の最後に到達するまでcurrent stateを取得しnext stateます。そして、あなたは得るthe final state。なんてクールなんだ!


5

著者は、状態をreduce関数のアキュムレータと考えています。例:

Final State = [Action1, Action2, ..., ActionN].reduce(reducer, Initial State);

reduce関数は関数型プログラミングに由来し、「reducer」という名前もFPに由来します。

ここでその名前を使うのは好きではありません。私は世界を行動後の単一の価値の結果として見ていません。ここの状態はオブジェクトです。例えば:

['eat', 'sleep'] === [addTodo('eat'), addTodo('sleep')].reduce(reducer, []);

このレデューサーは何も削減しません。そして、私はそれが何かを減らすかどうかは気にしません。Transducerという名前を付ける方が理にかなっています。


5

レデューサーがどこから来ているのか(関数型プログラミング)、そしてなぜそれらがリデューシング作業を行っていると見なされるのかを知っています(n個の入力項目を単一の戻り値に減らします-これは通常の関数が行うことです)。ただし、名前は単なる名前であり、バラはバラの名前です。あまり考えすぎないでください。ReduxプログラマーはIT担当者であり、コンテキストに固定されているため、それは理にかなっています。私たちの残りの部分は、青い犬を黄色い猫と呼ぶ発明者の権利を受け入れる必要があります;-)



1

減らす手段としてreduceと呼ばれるべきではありません。これらの関数は、ほとんどの場合、より多くを作ります。そしてそれを返します


1

Reduxレデューサーがどのように使用する関数に直接マッピングされているのかよくわかりませんでしreduceた。そこで、それらがどのように一致するかを確認するための例をいくつか示します。

最初にMDNArray.reduceドキュメントの標準レデューサー(MDNでは「アキュムレータ」と呼ばれます)関数を使用し、次に「Reduxは必要ないかもしれません」というブログ投稿Counter.jsの最後にあるDanAbramovの簡単な例を示します。

  • sum アキュムレータに値を追加します
  • reducer アキュムレータとの間で値を加算/減算します。

どちらの場合も、ここでは「状態」は単なる整数です。

アクションを状態に「蓄積」しています。これは、JavaScriptオブジェクトを変更するための不変の方法でもあります。

const sum = function(acc, val) {
    return acc + val;
};

const reducer = function(state, action) {
    switch (action) {
        case 'INCREMENT':
            return state + 1;
        case 'DECREMENT':
            return state - 1;
        default:
            return state;
    }
};

console.log('sum', [1, -1, 1].reduce(sum, 0));

console.log('reduce', ['INCREMENT', 'DECREMENT', 'INCREMENT'].reduce(reducer, 0));

console.log('sum', [1, 1, 1].reduce(sum, 0));

console.log('reduce', ['INCREMENT', 'INCREMENT', 'INCREMENT'].reduce(reducer, 0));


0

他の回答は、なぜそれがそのままの名前が付けられているのかをよく説明していますが、もっと多くの名前を付けてみましょう...

const origState = 0;
const actionOperators = {
    increment: (origState) => origState++,
    decrement: (origState) => origState--,
};
const anOperator = (aState, anAction) => actionOperators[anAction](aState);
const actions = ['increment', 'decrement', 'increment'];
const finalState = actions.reduce(anOperator, origState);

まず、reduceと呼ぶことができますuse anOperator with every action name and accumulated state, starting with origState。smalltalkではそれはと呼ばれactions inject: origState into: anOperatorます。しかし、実際にオペレーターに何を注入しますか?origStateとアクション名。そのため、Smalltalkメソッドでも名前はあまり明確ではありません。

actionOperators[increment]はReducerですが、アクションごとに実装されているため、actionOperatorと呼びます。状態は単なる引数です(そして別の引数は戻り値です)。

ただし、Reducerは、Googleの検索結果の上に表示するのに適した単語です。Reduxにも似ています。


0

以下のこのコードでは、アキュムレータをアクションとして、currentValueをreduxコンテキストの状態として考える必要があります。この例では、なぜ彼らがそれをレデューサーと名付けているのかがわかります。

const array1 = [1, 2, 3, 4];
const reducer = (accumulator, currentValue) => accumulator + currentValue;

// Main operation is 1 + 2 + 3 + 4 = 10
// but think of it as a stack like this: 

// | 2 | | 3 | | 4 | 
// |_1_| |_3_| |_6_| | 10 | => the 10 is in result

console.log(array1.reduce(reducer));
// expected output: 10

reduce()メソッドは、配列の各要素に対して(指定した)レデューサー関数を実行し、単一の出力値を生成します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.