Чому державні функції Redux називають редукторами?


82

Це частина офіційної документації Redux :

Це називається редуктором, оскільки це тип функції, до якої ви переходите Array.prototype.reduce(reducer, ?initialValue)

Для мене це не має особливого сенсу. Хтось може пояснити мені, чому їх насправді називають редукторами? Той факт, що вони повертають значення за замовчуванням (або вони мають значення аргументу за замовчуванням), не робить їх редукторами IMHO.


6
Вони є редукторами саме тому, що вони поводяться як функція, якій ви передаєте reduce, яка має доступ до значення за замовчуванням та іншого значення, і повертає вам потенційно трансформоване значення за замовчуванням. state -> action -> state
azium

2
троянда під будь-якою іншою назвою ... ймовірно, маркетинг; map / reduce - це модне слово зараз ...
dandavis

1
ось чому ви повинні почати думати самі і не покладатися на основи. Фреймворк - це здебільшого робота одного чи кількох розробників із власним баченням, як вирішити проблему, адаптовану користувачами Інтернету. Деякі фреймворки зрозуміли це правильно, однак переважно ні. хуртовина поцілунку, те саме чи менше не є рішенням. Це лише приклад багатьох там.
Codebeat

Відповіді:


71

Той факт, що вони повертають значення за замовчуванням (або вони мають значення аргументу за замовчуванням), не робить їх редукторами IMHO.

Редуктори не просто повертають значення за замовчуванням. Вони завжди повертають накопичення стану (виходячи з усіх попередніх та поточних дій).

Тому вони виступають як скорочувач стану. Кожного разу, коли викликається редукційний редуктор, стан передається разом із дією (state, action). Потім цей стан зменшується (або накопичується) на основі дії, а потім повертається наступний стан. Це один цикл класики foldабо reduceфункції.

Як підсумував @azium state -> action -> state.


7
Хам за цією логікою, чи не слід їх називати збільшувачами, а не редукторами? Жодні дані ніколи не зменшуються, їх додавання: / lol
Jamie Hutber

16
@JamieHutber Я думаю, вам трохи не вистачає значення редуктора в цьому контексті. редуктор приймає потік (або колекцію) предметів і об'єднує їх в єдиний елемент. У цьому випадку всі дії (через час) - це колекція предметів, а держава - це єдиний елемент. Мати сенс?
Девін Тріон

7
ха-ха зараз я бачу. Отже, це в основному просто приховування їх. Чому б тоді не назвати це злиттям: P Дякую за те, що це мені зрозуміло :)
Джеймі Хатбер

20
Слава богу, я не єдиний вважаю, що зменшувач імен трохи відстоює щонайменше 2000 переглядів цього повідомлення на той час, коли я це пишу. Той факт, що хтось навіть готовий активізувати зусилля, щоб розкопати, чому це називається редуктором, не означає, що це справді трохи відхилено? Якщо це називається редуктором, оскільки це тип функції, який ви передали б Array.prototype.reduce, це все одно, що давайте називати апельсин соковижималкою, тому що ми передаємо апельсин object.prototype.juicer, чи не слід називати це фруктом?
Yini

2
Я згоден, це зовсім не інтуїтивна назва. Логічно, щоб називатися редуктором, це мало би щось зменшити. Якби це взяло цілий масив змін стану разом із станом і об’єднало їх у єдиний стан відразу, то це було б інтуїтивно зрозумілою назвою.
угода Пітера Евана

20

Якщо ви вважаєте низку дій у вашому додатку схожими на список або, можливо, більше як на потік, це може мати більше сенсу.

Візьмемо цей надуманий приклад:

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

Перший аргумент - це функція форми (Int, String) => Int. Разом з початковим значенням ви проходитеreduce те, що можна було б назвати "функцією редуктора", і отримуєте результат обробки серії елементів. Отже, можна сказати, функція редуктора описує, що робиться з кожним наступним окремим елементом для зміни результату. Іншими словами, функція редуктора приймає попередні вихідні та наступні значення і обчислює наступний вихідний результат.

Це аналогічно тому, що робить редуктор Redux: він бере попередній стан і поточну дію, і обчислює наступний стан.

У справжньому функціональному стилі програмування ви можете концептуально стерти значення, що застосовується до аргументів та результату, і просто зосередитись на "формі" входів та результатів.

На практиці редуктори Redux зазвичай є ортогональними, в тому сенсі, що для даної дії вони не всі вносять зміни до одних і тих же властивостей, що полегшує розподіл їх обов’язків та агрегування результату combineReducers.


Так, ти маєш рацію, це має більше сенсу, коли я думаю про дії, подібні до потоку. Класно, виправдайте це!
Антон Савченко

Це було те, як я спочатку це розумів, але, схоже, це не так, як будь-яка реалізація магазину, яку я бачив до цього часу, реалізувала це ...
Борис Калленс

16

Як уже зазначалося, назва пов'язана з поняттям редуктора у функціональному програмуванні. Також вам може бути корисним визначення словника редуктора Мерріам-Вебстер:

1а. зближувати або викликати сходження: консолідувати (звести усі питання до одного)

Редуктор консолідує дії в єдиний об'єкт, що представляє стан програми.


8

Причина, чому редуктор-редуктор називається a, reducerполягає в тому, що ви можете "зменшити" a collection of actionsта an initial state(магазину), на яких слід виконати ці дії, щоб отримати результат final state.

Як? Щоб відповісти на це, дозвольте мені ще раз визначити редуктор:

Метод зменшення () застосовує function (reducer)проти accumulatorмасиву та кожного значення масиву (зліва направо), щоб зменшити його до одного значення.

А що робить редукційний редуктор?

Редуктор - це параметр, functionякий приймає поточний стан і дію і повертає наступний стан. Зверніть увагу, що стан є тим accumulated, що кожна дія над колекцією застосовується для зміни цього стану.

Отже, за умови a collection of actions, редуктор застосовується до кожного значення колекції (зліва направо). Перший раз він повертає initial value. Тепер редуктор знову застосовується до цього початкового стану і виконується перша дія для повернення наступного стану. І наступний елемент колекції (дія) застосовується кожного разу, current stateщоб отримати, next stateпоки він не досягне кінця масиву. І тоді, ви отримуєте the final state. Як це круто!


5

Автор мислить державу як накопичувач функції редукції. Приклад:

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

Функція зменшення походить від функціонального програмування, назва "редуктор" також походить від FP.

Мені не подобається використовувати цю назву тут. Тому що я не сприймаю світ як єдиний ціннісний результат після дій. Держава тут є об’єктом. Наприклад:

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

Цей редуктор взагалі нічого не зменшує. І мені байдуже, зменшує це щось чи ні. Присвоєння йому імені перетворювача матиме більше сенсу.


5

Ми знаємо, звідки беруться Редуктори (функціональне програмування), і чому їх можна вважати виконуючими скорочувальну роботу (зменшити n вхідних елементів до одного поверненого значення - саме це, як передбачається, виконують звичайні функції). Однак: назва - це просто назва, як троянда - назва троянди. Не думайте занадто багато. Програмери Redux - це ІТ-спеціалісти, вони замикаються у своєму контексті і там це має сенс. Решта з нас повинні прийняти право винахідника називати блакитну собаку жовтою кішкою ;-)


2

Як би ми зараз називали це Дедуцером . Він визначає новий стан на основі попереднього стану та вхідної дії.


1

Їх не слід називати зменшенням, оскільки зменшення означає зменшення, ці функції найчастіше роблять більше. а потім поверніть його


1

Я не міг зрозуміти, як редуктор Redux безпосередньо зіставлявся з функцією, якою ви користуєтесь reduce, тож ось кілька прикладів, щоб побачити, як вони збігаються.

Спочатку функція стандартного редуктора (у MDN називається "накопичувачем") із документації MDN Array.reduce, а потім спрощений приклад Дана Абрамова Counter.jsв кінці його публікації в блозі "Вам може не знадобитися Redux" .

  • 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]є Редуктором, але я б скоріше назвав його і actionOperator, оскільки він реалізований для кожної дії. Стан - це лише аргумент (і ще один як повернене значення).

Однак редуктор - найкраще слово знаходитись у верхній частині результатів пошуку Google. Це також схоже на Redux.


0

У цьому коді нижче вам просто потрібно розглядати накопичувач як дії і currentValue як стан у контексті відновлення. на цьому прикладі ви дізнаєтесь, чому вони називають його також редуктором.

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 () виконує функцію редуктора (яку ви надаєте) для кожного елемента масиву, в результаті чого отримується одне вихідне значення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.