Redux의 상태 함수를 리듀서라고 부르는 이유는 무엇입니까?


82

이것은 공식 Redux 문서의 일부입니다 .

그것은 당신이 전달할 함수의 유형이기 때문에 감속기라고 불립니다. Array.prototype.reduce(reducer, ?initialValue)

나에게는 그다지 말이되지 않습니다. 누군가가 실제로 감속기라고 불리는 이유를 설명해 주시겠습니까? 기본값을 반환한다는 사실 (또는 기본 인수 값이 있음)은 감속기를 IMHO로 만들지 않습니다.


6
reduce기본값과 다른 값에 액세스 할 수 있고 잠재적으로 변환 된 기본값을 다시 제공하는에 전달하는 함수처럼 동작하기 때문에 정확히 감속기 입니다. state -> action -> state
azium

2
다른 이름의 장미 ... 아마도 마케팅; map / reduce는 지금 유행어입니다 ...
dandavis

1
그렇기 때문에 자신을 생각하고 프레임 워크에 의존하지 않아야합니다. 프레임 워크는 대부분 인터넷 사용자가 조정 한 문제를 해결하는 방법에 대한 자신의 비전을 가진 개발자 한 명 또는 소수의 작업입니다. 일부 프레임 워크는 제대로 작동하지만 대부분 그렇지 않습니다. 키스의 눈보라, 같거나 적은 것은 해결책이 아닙니다. 이것은 많은 사람들의 예일뿐입니다.
Codebeat

답변:


71

기본값을 반환한다는 사실 (또는 기본 인수 값이 있음)은 감속기를 IMHO로 만들지 않습니다.

기어가없는 단지 기본 값을 반환합니다. 항상 상태의 누적을 반환합니다 (모든 이전 및 현재 작업을 기반으로 함).

따라서 그들은 상태를 줄이는 역할을합니다 . redux 감속기가 호출 될 때마다 상태가 action과 함께 전달됩니다 (state, action). 이 상태는 작업을 기반으로 축소 (또는 누적) 된 후 다음 상태가 반환됩니다. 이것은 클래식 fold또는 reduce기능의 한주기입니다 .

@azium이 state -> action -> state.


7
이 논리에 따르면 그들은 감속기보다는 증가 기라고 부르지 않아야합니까? / 롤 : 데이터가 사상 존재가 추가 감소되고 있지
제이미 Hutber을

16
@JamieHutber 나는이 맥락에서 감속기의 의미를 약간 놓친 것 같습니다. reducer는 항목의 스트림 (또는 컬렉션)을 가져와 단일 항목으로 결합합니다. 이 경우 모든 작업 (시간별)은 항목 모음이고 상태는 단일 항목입니다. 말이 되나?
다빈 Tryon

7
ㅋㅋ 지금 알겠습니다. 그래서 기본적으로 그것들을 연결합니다. 그런데 왜 합병을 호출하지 : P 감사는 :) 나에게 지우 만들기위한
제이미 Hutber

20
감사합니다. 저는 이름 감속기가 제가이 글을 쓰는 시점에이 게시물에 대해 적어도 2,000 개의 뷰에서 약간 벗어났다고 생각하는 유일한 사람이 아닙니다. 누군가가 리듀서라고 불리는 이유를 파 헤치려는 노력을 기꺼이 돌린다는 사실은 그것이 실제로 약간 벗어난 것을 의미하지 않습니까? Array.prototype.reduce에 전달하는 함수의 유형이기 때문에 감속기라고 부르면 오렌지를 object.prototype.juicer에 전달하기 때문에 orange를 juicer라고 부르거나 과일이라고 부르지 않습니까?
Yini

2
동의합니다. 그것은 전혀 직관적 인 이름이 아닙니다. 논리적으로 감속기라고 부르려면 무언가를 줄여야합니다. 상태와 함께 전체 상태 변경 배열을 가져 와서 한 번에 하나의 상태로 결합하면 직관적 인 이름이됩니다.
Peter Evan Deal

20

앱의 일련의 작업이 목록과 같거나 스트림과 비슷하다고 생각하면 더 합리적 일 수 있습니다.

이 인위적인 예를 보자 :

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

첫 번째 인수는 형식의 함수입니다 (Int, String) => Int. 초기 값과 함께 reduce"리듀서 함수"라고하는 것을 전달 하고 일련의 항목을 처리 한 결과를 얻습니다. 따라서 감속기 기능은 결과를 변경하기 위해 연속적인 개별 항목에 대해 수행되는 작업을 설명합니다. 즉, 감속기 함수는 이전 출력과 다음 값을 취하고 다음 출력을 계산합니다.

이것은 Redux 감속기가 수행하는 작업과 유사합니다. 이전 상태와 현재 작업을 취하고 다음 상태를 계산합니다.

진정한 함수형 프로그래밍 스타일에서는 인수와 결과에 적용된 의미를 개념적으로 지우고 입력 및 출력의 "모양"에만 집중할 수 있습니다.

실제로 Redux 감속기는 일반적으로 주어진 작업에 대해 모두 동일한 속성을 변경하지 않으므로 책임을 분할하고 출력을 combineReducers.


예, 맞습니다. 스트림과 같은 행동에 대해 생각할 때 더 의미가 있습니다. 멋지다, 예쁘다!
Anton Savchenko

내가 처음에 그것을 이해하는 방법이 있었지만이 될 것 같지 않습니다 어떻게 지금까지 ... 그것을 구현 한 본 적이 가게 구현의
보리스 CALLENS

16

이미 언급했듯이 이름은 함수형 프로그래밍에서 감속기의 개념과 관련이 있습니다. 감속기의 Merriam-Webster 사전 정의가 도움이 될 수도 있습니다.

1a. 함께 그리거나 수렴시키다 : 통합 (모든 질문을 하나로 줄임)

감속기는 작업을 애플리케이션 상태를 나타내는 단일 객체로 통합합니다.


8

redux 감속기 가 a라고 불리는 이유 는 결과를 얻기 위해 이러한 작업을 수행 할 reducera collection of actionsinitial state(저장소)를 "줄일"수 있기 때문 final state입니다.

어떻게? 이에 답하기 위해 감속기를 다시 정의하겠습니다.

감소 () 메소드는 적용 function (reducer)대해 accumulator상기 어레이의 각각의 값 (의 왼쪽에서 오른쪽으로) 하나의 값으로 감소시키기 위해.

그리고 redux 감속기는 무엇을합니까?

감속기는 function현재 상태와 동작을 취하고 다음 상태를 반환 하는 순수 입니다. 상태는 accumulated컬렉션에 대한 각 작업이이 상태를 변경하기 위해 적용되는 것과 같습니다.

따라서가 주어지면 collection of actions감속기가 컬렉션의 각 값 (왼쪽에서 오른쪽으로)에 적용됩니다. 처음에는 initial value. 이제 감속기가이 초기 상태와 다음 상태를 반환하는 첫 번째 동작에 다시 적용됩니다. 그리고 다음 컬렉션 항목 (작업)은 배열의 끝에 도달 할 때까지 current state가져 오기 위해 매번 적용 next state됩니다. 그런 다음 the final state. 얼마나 멋진가요!


5

저자는 상태를 감소 기능의 누산기로 생각합니다. 전의:

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

reduce 기능은 Functional Programming에서 나왔고 "reducer"라는 이름도 FP에서 나왔습니다.

나는 여기에서 그 이름을 사용하는 것을 좋아하지 않습니다. 나는 세상을 행동 후 하나의 가치 결과로 보지 않기 때문입니다. 여기서 상태는 객체입니다. 예를 들면 :

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

감속기는 전혀 감소하지 않습니다. 그리고 나는 그것이 아무것도 줄이든 말든 상관하지 않습니다. Transducer 로 이름을 지정하는 것이 더 합리적입니다.


5

우리는 Reducer가 어디에서 왔는지 (함수 프로그래밍), 왜 그들이 축소 작업을 수행하는 것으로 간주되는지 알고 있습니다 (n 개의 입력 항목을 단일 반환 값으로 줄이십시오-이는 정상적인 함수가하는 일입니다). 그러나 이름은 장미의 이름 인 것처럼 이름 일뿐입니다. 너무 많이 생각하지 말라. Redux progammer는 IT 인력이며, 컨텍스트에 갇혀 있으며 그게 합리적입니다. 나머지 우리는 파란 개를 노란 고양이라고 부르는 발명가의 권리를 받아 들여야합니다 ;-)


2

이제 부터는 Deducer 라고 부를 까요 ? 이전 상태와 들어오는 작업을 기반으로 새로운 상태를 추론합니다.


1

그들은 더 적게 만드는 수단을 줄이기 위해 reduce라고 부르지 않아야하며, 이러한 함수는 가장 자주 더 많이 만듭니다. 그런 다음 반환


1

Redux 감속기가와 함께 사용하는 함수에 직접 매핑되는 방법을 알 수 없었 reduce으므로 여기에 몇 가지 예가 있습니다.

먼저 MDN Array.reduce 문서 의 표준 감속기 (MDN에서 '누적 기'라고 함) 기능을 사용한 다음 'You might not need Redux'블로그 게시물Counter.js 끝에있는 Dan Abramov의 단순화 된 예입니다 .

  • 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. 스몰 토크에서는 actions inject: origState into: anOperator. 그러나 실제로 작업자에게 무엇을 주입합니까? origState 및 작업 이름. 따라서 스몰 토크에서도 메서드 이름은 명확하지 않습니다.

actionOperators[increment]감속기이지만 각 작업에 대해 구현되기 때문에 차라리 이것을 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.