Pourquoi les fonctions d’état de Redux s’appellent-elles des réducteurs?

Ceci est une partie de la documentation officielle Redux :

On l’appelle un réducteur car c’est le type de fonction que vous passez à Array.prototype.reduce(reducer, ?initialValue)

Cela n’a pas beaucoup de sens pour moi. Quelqu’un pourrait-il m’expliquer pourquoi on les appelle en réalité des réducteurs? Le fait qu’ils retournent une valeur par défaut (ou qu’ils ont une valeur d’argument par défaut) ne les rend pas moins efficaces.

Le fait qu’ils retournent une valeur par défaut (ou qu’ils ont une valeur d’argument par défaut) ne les rend pas moins efficaces.

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

Par conséquent, ils agissent en tant que réducteur d’état. Chaque fois qu’un redux reducer est appelé, l’état est passé avec l’action (state, action) . Cet état est ensuite réduit (ou accumulé) en fonction de l’action, puis l’état suivant est renvoyé. C’est un cycle du fold classique ou de reduce fonction de reduce .

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

Si vous considérez que la série d’actions de votre application ressemble à une liste, ou plutôt à un stream, cela pourrait être plus logique.

Prenez cet exemple:

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

Le premier argument est une fonction de la forme (Int, Ssortingng) => Int . En plus d’une valeur initiale, vous reduce ce que l’on pourrait appeler une “fonction de reduce “, et vous obtenez le résultat du traitement de la série d’éléments. Ainsi, vous pourriez dire que la fonction réducteur décrit ce qui est fait avec chaque élément individuel successif pour modifier le résultat. En d’autres termes, la fonction réducteur prend la valeur 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 vrai style de functional programming, vous pouvez effacer conceptuellement la signification appliquée 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 ne modifient pas tous les mêmes propriétés, ce qui facilite la répartition des responsabilités et l’agrégation des résultats avec combineReducers .

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

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

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

La raison pour laquelle on l’appelle un reducer est que vous pouvez “réduire” un collection of actions et un initial state (du magasin) sur lequel effectuer ces actions pour obtenir l’ final state résultant.

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

La méthode Reduce () applique une function à un accumulator et à chaque valeur du tableau (de gauche à droite) pour la réduire à une valeur unique.

Et que fait un réducteur de redux?

Le réducteur est une function pure qui prend l’état actuel et une action et retourne l’état suivant. Notez que l’état est accumulated lorsque 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 la initial value . Maintenant, le réducteur est à nouveau appliqué à cet état initial et à la première action pour renvoyer l’état suivant. Et le prochain élément de collection (action) est appliqué à chaque fois sur l’ current state pour obtenir l’ next state jusqu’à ce qu’il atteigne la fin du tableau. Et puis, vous obtenez the final state . À quel point cela est cool!

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

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

La fonction de réduction provient de la functional programming, 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 object. Par exemple:

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

Ce réducteur ne réduit rien du tout. Et ça m’est égal de réduire quoi que ce soit ou pas. Le nommer comme transducteur aura plus de sens.

Nous soaps d’où proviennent les réducteurs (functional programming), et pourquoi ils peuvent ê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 est exactement ce que font les fonctions normales). Cependant: le nom est juste un nom, comme rose est le nom d’une rose. Ne pense pas trop. Les progammateurs Redux sont des informaticiens, ils sont bloqués dans leur contexte et cela a du sens. Le rest d’entre nous doit accepter le droit de l’inventeur d’appeler un chien bleu un chat jaune 😉

D’autres réponses expliquent bien pourquoi il est nommé tel qu’il est 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 . Dans smalltalk, il est appelé actions inject: origState into: anOperator . Mais qu’est-ce que vous injectez réellement dans l’opérateur? L’origState ET les noms des actions. Donc, 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ère l’appeler et actionOperator car il est implémenté pour chaque action. L’état n’est qu’un argument (et un autre comme valeur de retour).

Réducteur est cependant un meilleur mot pour être au sumt des résultats de recherche Google. Il est également similaire à Redux.

Je ne pouvais pas vraiment voir comment un réducteur Redux directement mappé à la fonction que vous utilisez avec reduce , alors voici quelques exemples pour voir comment ils correspondent.

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

 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