¿Por qué las funciones de estado de Redux se llaman reductores?

82

Esta es una parte de la documentación oficial de Redux :

Se llama reductor porque es el tipo de función a la que pasaría Array.prototype.reduce(reducer, ?initialValue)

No tiene mucho sentido para mí. ¿Alguien podría explicarme por qué en realidad se llaman reductores? El hecho de que devuelvan un valor predeterminado (o que tengan un valor de argumento predeterminado) no los convierte en reductores en mi humilde opinión.

Anton Savchenko
fuente
6
Son reductores exactamente porque se comportan como la función a la que pasa reduce, que tiene acceso al valor predeterminado y a otro valor, y le devuelve su valor predeterminado potencialmente transformado. state -> action -> state
azium
2
una rosa con cualquier otro nombre ... probablemente marketing; mapa / reducir es una palabra de moda ahora ...
dandavis
1
por eso debes empezar a pensar por ti mismo y no depender de un marco. Un framwork es principalmente el trabajo de uno o varios desarrolladores con su propia visión de cómo resolver un problema adaptado por los usuarios de Internet. Algunos frameworks lo hicieron bien, pero la mayoría no. una ventisca de un beso, lo mismo o menos no es una solución. Este es solo un ejemplo de muchos que existen.
Codebeat

Respuestas:

71

El hecho de que devuelvan un valor predeterminado (o que tengan un valor de argumento predeterminado) no los convierte en reductores en mi humilde opinión.

Los reductores no solo devuelven valores predeterminados. Siempre devuelven la acumulación del estado (en función de todas las acciones anteriores y actuales).

Por tanto, actúan como reductores de estado. Cada vez que se llama a un reductor redux, el estado se transfiere con la acción (state, action). Este estado luego se reduce (o acumula) según la acción, y luego se devuelve el siguiente estado. Este es un ciclo del clásico foldo reducefunción.

Como resumió @azium state -> action -> state.

Davin Tryon
fuente
7
Humm, según esta lógica, ¿no deberían llamarse incrementadores en lugar de reductores? Ningún dato se reduce nunca, se agrega: / lol
Jamie Hutber
16
@JamieHutber Creo que extrañas un poco el significado de reductor en este contexto. reductor toma un flujo (o colección) de elementos y los combina en un solo elemento. En este caso, todas las acciones (a lo largo del tiempo) son la colección de elementos y el estado es el elemento único. ¿Tener sentido?
Davin Tryon
7
lol ya veo. Así que básicamente se trata de concatenarlos. Entonces, ¿por qué no llamarlo fusión? Gracias por dejarme claro :)
Jamie Hutber
20
Gracias a Dios, no soy el único que piensa que el reductor de nombres está un poco fuera de al menos 2,000 visitas en esta publicación en el momento en que escribo esto. El hecho de que alguien esté dispuesto a hacer el esfuerzo de descubrir por qué se llama reductor, ¿no implica que esté un poco fuera de lugar? Si se llama reductor porque es el tipo de función que le pasarías a Array.prototype.reduce, es como llamar a la naranja un exprimidor porque pasamos naranja a object.prototype.juicer, ¿o no deberíamos llamarlo una fruta?
Yini
2
Estoy de acuerdo, no es en absoluto un nombre intuitivo. Lógicamente, para llamarse reductor debería reducir algo. Si tomara una serie completa de cambios de estado junto con un estado y los combinara en un solo estado de una vez, entonces sería un nombre intuitivo.
Peter Evan Deal
20

Si considera que la serie de acciones en su aplicación es como una lista, o tal vez más como una transmisión, podría tener más sentido.

Tome este ejemplo artificial:

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

El primer argumento es una función de la forma (Int, String) => Int. Junto con un valor inicial, pasa reducelo que podría llamarse una "función reductora" y obtiene el resultado de procesar la serie de elementos. Podría decirse que la función reductora describe lo que se hace con cada elemento individual sucesivo para cambiar el resultado. En otras palabras, la función reductora toma la salida anterior y el siguiente valor, y calcula la siguiente salida.

Esto es análogo a lo que hace un reductor Redux: toma el estado anterior y la acción actual, y calcula el siguiente estado.

En el verdadero estilo de programación funcional, puede borrar conceptualmente el significado aplicado a los argumentos y el resultado, y simplemente centrarse en la "forma" de las entradas y salidas.

En la práctica, los reductores Redux suelen ser ortogonales, en el sentido de que para una acción determinada, no todos realizan cambios en las mismas propiedades, lo que facilita la división de responsabilidades y la agregación de la salida combineReducers.

acjay
fuente
Sí, tienes razón, tiene más sentido cuando pienso en acciones más como en una transmisión. ¡Genial, apúrate!
Anton Savchenko
Así fue como lo entendí inicialmente, pero no parece ser así como ninguna de las implementaciones de tienda que he visto hasta ahora lo ha implementado ...
Boris Callens
16

Como ya se mencionó, el nombre está relacionado con el concepto de reductor en la programación funcional. También puede encontrar útil la definición de reductor del diccionario Merriam-Webster:

1a. para juntar o hacer converger: consolidar (reducir todas las preguntas a una)

El reductor consolida acciones en un solo objeto que representa el estado de la aplicación.

Drew Goodwin
fuente
8

La razón por la que un redux reductor se llama a reduceres porque podría "reducir" ay collection of actionsun initial state(de la tienda) en el que realizar estas acciones para obtener el resultado final state.

¿Cómo? Para responder a eso, déjame definir un reductor nuevamente:

El método reduce () aplica un function (reducer)contra un accumulatory cada valor de la matriz (de izquierda a derecha) para reducirlo a un solo valor.

¿Y qué hace un reductor redux?

El reductor es un puro functionque toma el estado actual y una acción, y devuelve el siguiente estado. Tenga en cuenta que el estado es accumulatedcuando se aplica cada acción en la colección para cambiar este estado.

Entonces, dado a collection of actions, el reductor se aplica a cada valor de la colección (de izquierda a derecha). La primera vez, devuelve el initial value. Ahora, el reductor se aplica nuevamente en este estado inicial y la primera acción es devolver el siguiente estado. Y el siguiente elemento de colección (acción) se aplica cada vez en el current statepara obtener el next statehasta que llega al final de la matriz. Y luego, obtienes the final state. ¡Cuan genial es eso!

code4kix
fuente
5

El autor piensa que el estado es el acumulador de la función de reducción. Ex:

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

La función de reducción proviene de Programación funcional, el nombre "reductor" también proviene de FP.

No me gusta usar ese nombre aquí. Porque no veo el mundo como un resultado de valor único después de las acciones. El estado aquí es un objeto. Por ejemplo:

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

Este Reductor no reduce nada en absoluto. Y no me importa que reduzca nada o no. Nombrarlo como Transductor tendrá más sentido.

Joshmori
fuente
5

Sabemos de dónde provienen los Reductores (programación funcional) y por qué se puede considerar que están haciendo un trabajo de reducción (reducir n elementos de entrada a un solo valor de retorno, que es justo lo que se supone que hacen las funciones normales). Sin embargo: el nombre es solo un nombre, como rosa es el nombre de una rosa. No pienses demasiado. Los programadores de Redux son gente de TI, están encerrados en su contexto y ahí tiene sentido. El resto de nosotros tenemos que aceptar el derecho del inventor a llamar gato amarillo a un perro azul ;-)

René Baron
fuente
2

¿Qué tal si lo llamamos Deducer de ahora en adelante? Deduce el nuevo estado basándose en el estado anterior y la acción entrante.

Rutger van Dijk
fuente
1

No deben llamarse reducir ya que reducir significa hacer menos, estas funciones suelen producir más. y luego devuélvelo

mella
fuente
1

No pude ver cómo un reductor de Redux se asigna directamente a la función con la que usa reduce, así que aquí hay un par de ejemplos para ver cómo coinciden.

Primero, una función de reducción estándar (llamada 'acumulador' en MDN) de la documentación de MDN Array.reduce y luego un ejemplo simplificado de Dan Abramov Counter.jsal final de su publicación de blog 'Es posible que no necesite Redux' .

  • sum agrega un valor al acumulador
  • reducer suma / resta un valor a / del acumulador.

En ambos casos, aquí el 'estado' es solo un número entero.

Estás "acumulando" las acciones en el estado. Esta es también la forma inmutable de modificar cualquier objeto 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));

icc97
fuente
0

Otras respuestas explican bien por qué se llama así, pero intentemos nombrar más cosas ...

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

Primero, reducepodría llamarse use anOperator with every action name and accumulated state, starting with origState. En smalltalk se llama actions inject: origState into: anOperator. Pero, ¿qué inyecta realmente en el operador? El origState Y los nombres de las acciones. Así que incluso en Smalltalk, los nombres de los métodos no son muy claros.

actionOperators[increment]es un Reducer, pero prefiero llamarlo y actionOperator porque está implementado para cada acción. El estado es solo un argumento (y otro como valor de retorno).

Reductor es, sin embargo, una palabra mejor para estar en la parte superior de los resultados de búsqueda de Google. También es similar a Redux.

Rivenfall
fuente
0

En este código a continuación, solo necesita pensar en el acumulador como las acciones y currentValue como un estado en el contexto redux. Con este ejemplo descubrirás por qué también lo nombran reductor.

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

El método reduce () ejecuta una función reductora (que usted proporciona) en cada elemento de la matriz, lo que da como resultado un único valor de salida.

Ehsan Ahmadi
fuente