web-dev-qa-db-fra.com

Pourquoi les fonctions d'état de Redux sont-elles appelées réducteurs?

Ceci est une partie de la documentation officielle de Redux :

Il s’appelle réducteur car c’est le type de fonction que vous transmettez à Array.prototype.reduce(reducer, ?initialValue)

Cela n'a pas beaucoup de sens pour moi. Quelqu'un pourrait-il m'expliquer pourquoi ils s'appellent en réalité des réducteurs? Le fait qu'ils renvoient une valeur par défaut (ou qu'ils aient une valeur d'argument par défaut) ne fait pas d'eux des réducteurs IMHO.

61
Anton Savchenko

Le fait qu'ils renvoient une valeur par défaut (ou qu'ils aient une valeur d'argument Par défaut) ne fait pas d'eux des réducteurs IMHO.

Les réducteurs ne pas seulement renvoient des valeurs par défaut. Ils renvoient toujours l'accumulation de l'état (basée sur toutes les actions précédentes et actuelles).

Par conséquent, ils agissent comme un réducteur d'état. Chaque fois qu'un réducteur redux est appelé, l'état est passé avec l'action (state, action). Cet état est alors réduit (ou accumulé) en fonction de l'action, puis l'état suivant est renvoyé. Il s’agit d’un cycle de la fonction fold ou reduce classique.

Comme @azium résume avec state -> action -> state.

59
Davin Tryon

Si vous considérez la série d'actions dans votre application comme une liste, ou peut-être davantage comme un flux, cela peut sembler plus logique.

Prenons cet exemple artificiel:

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

Le premier argument est une fonction de la forme (Int, String) => Int. Avec une valeur initiale, vous transmettez reduce à ce que l’on pourrait appeler une "fonction de réduction" et vous obtenez le résultat du traitement de la série d’éléments. Vous pourriez donc dire que la fonction de réduction décrit ce qui est fait avec chaque élément individuel successif pour modifier le résultat. En d’autres termes, la fonction de réduction prend la sortie précédente et la valeur suivante et calcule la sortie suivante.

Ceci est analogue à ce que fait un réducteur Redux: il prend l’état précédent et l’action en cours et calcule l’état suivant.

En véritable style de programmation fonctionnel, vous pouvez conceptuellement effacer le sens appliqué aux arguments et au résultat, et vous concentrer uniquement sur la "forme" des entrées et des sorties.

En pratique, les réducteurs Redux sont généralement orthogonaux, en ce sens que, pour une action donnée, ils n'apportent pas tous des modifications aux mêmes propriétés, ce qui facilite la répartition des responsabilités et l'agrégation de la sortie avec combineReducers.

19
acjay

Comme déjà mentionné, le nom est lié au concept de réducteur en programmation fonctionnelle. Vous pouvez également trouver la définition du réducteur du dictionnaire Merriam-Webster utile:

1a. rapprocher ou faire converger: consolider (réduire toutes les questions à une seule)

Le réducteur consolide les actions en un seul objet représentant l'état de l'application.

12
Drew Goodwin

La raison pour laquelle un redux reducer est appelé reducer est parce que vous pouvez "réduire" un collection of actions et un initial state (du magasin) sur lesquels effectuer ces actions pour obtenir le final state résultant. 

Comment? Pour répondre à cela, laissez-moi définir à nouveau un réducteur:

La méthode reduction () applique une function (reducer) à une accumulator et à chaque valeur du tableau (de gauche à droite) pour le réduire à un seul valeur.

Et que fait un réducteur de redux?

Le réducteur est un function pur qui prend l'état actuel et un action, et retourne à l'état suivant. Notez que l'état est accumulated car chaque action de la collection est appliquée pour modifier cet état.

Donc, étant donné un collection of actions, le réducteur est appliqué à chaque valeur de la collection (de gauche à droite). La première fois, il renvoie le initial value. Maintenant, le réducteur est appliqué à nouveau sur cet état initial et sur la première action pour renvoyer l'état suivant. Et le prochain élément de collection (action) est appliqué à chaque fois sur le current state pour obtenir le next state jusqu'à ce qu'il atteigne la fin du tableau. Et puis, vous obtenez the final state. À quel point cela est cool!

4
code4kix

L’auteur pense que l’état est l’accumulateur de la fonction de réduction. Ex:

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

La fonction de réduction provient de la programmation fonctionnelle, le nom "réducteur" provient également de FP. 

Je n'aime pas utiliser ce nom ici. Parce que je ne vois pas le monde comme un résultat unique après les actions. L'état ici est un objet. Par exemple:

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

Ce Réducteur ne réduit rien du tout. Et je m'en fous qu'il réduise quoi que ce soit ou non. Le nommer en tant que Transducer aura plus de sens.

3
Wangchou Lu

Nous savons d'où viennent les réducteurs (programmation fonctionnelle) et pourquoi ils pourraient être considérés comme effectuant un travail de réduction (réduire n éléments d'entrée à une seule valeur de retour - ce qui correspond exactement aux fonctions normales suppostées). Cependant: le nom n’est qu’un nom, comme rose est le nom d’une rose. Ne pense pas trop. Les progamers Redux sont des informaticiens, ils sont enfermés dans leur contexte et c'est logique. Le reste d'entre nous doit accepter le droit de l'inventeur d'appeler un chat bleu un chat jaune ;-) 

3
René Baron

On ne devrait pas les appeler réduire comme moyen de faire moins, ces fonctions font le plus souvent plus. et ensuite le retourner

1
nick

Je ne comprenais pas vraiment comment un réducteur Redux était directement mappé sur la fonction que vous utilisiez avec reduce. Voici donc quelques exemples pour voir comment ils correspondent.

Tout d'abord, une fonction de réduction standard (appelée «accumulateur» dans MDN) à partir de MDN Array.reduce documentation, puis un exemple simplifié du Counter.js de Dan Abramov à la fin de son 'Vous n'avez peut-être pas besoin de Redux 'article de blog .

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

console.log([0, 1, 2, 3].reduce(sum, 0));
// 6

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

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

0
icc97

D'autres réponses expliquent bien pourquoi le nom est tel quel, mais essayons de nommer plus de choses ...

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);

Tout d'abord, reduce pourrait s'appeler use anOperator with every action name and accumulated state, starting with origState. En Smalltalk, cela s'appelle actions inject: origState into: anOperator. Mais que injectez-vous réellement dans l'opérateur? L'origine et les noms d'action. Ainsi, même dans la méthode Smalltalk, les noms ne sont pas très clairs.

actionOperators[increment] est un réducteur, mais je préférerais l'appeler ainsi actionOperator car il est implémenté pour chaque action. L'état est juste un argument (et un autre comme valeur de retour).

Réducteur est toutefois un meilleur mot pour être au-dessus des résultats de recherche Google. C'est aussi similaire à Redux.

0
Rivenfall

Dans ce code ci-dessous, il vous suffit de penser à l'accumulateur en tant qu'actions et à currentValue en tant qu'état dans un contexte redux. avec cet exemple, vous découvrirez pourquoi ils le nomment aussi comme réducteur.

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

La méthode reduction () exécute une fonction de réduction (fournie par vous) sur chaque élément du tableau, générant une seule valeur de sortie.

0
Ehsan Ahmadi

Que diriez-vous que nous l'appelons Déducteur à partir de maintenant. Il en déduit le nouvel état en fonction de l'état précédent et de l'action entrante.

0
Rutger van Dijk