이것은 공식 Redux 문서의 일부입니다 .
그것은 당신이 전달할 함수의 유형이기 때문에 감속기라고 불립니다.
Array.prototype.reduce(reducer, ?initialValue)
나에게는 그다지 말이되지 않습니다. 누군가가 실제로 감속기라고 불리는 이유를 설명해 주시겠습니까? 기본값을 반환한다는 사실 (또는 기본 인수 값이 있음)은 감속기를 IMHO로 만들지 않습니다.
이것은 공식 Redux 문서의 일부입니다 .
그것은 당신이 전달할 함수의 유형이기 때문에 감속기라고 불립니다.
Array.prototype.reduce(reducer, ?initialValue)
나에게는 그다지 말이되지 않습니다. 누군가가 실제로 감속기라고 불리는 이유를 설명해 주시겠습니까? 기본값을 반환한다는 사실 (또는 기본 인수 값이 있음)은 감속기를 IMHO로 만들지 않습니다.
답변:
기본값을 반환한다는 사실 (또는 기본 인수 값이 있음)은 감속기를 IMHO로 만들지 않습니다.
기어가없는 단지 기본 값을 반환합니다. 항상 상태의 누적을 반환합니다 (모든 이전 및 현재 작업을 기반으로 함).
따라서 그들은 상태를 줄이는 역할을합니다 . redux 감속기가 호출 될 때마다 상태가 action과 함께 전달됩니다 (state, action)
. 이 상태는 작업을 기반으로 축소 (또는 누적) 된 후 다음 상태가 반환됩니다. 이것은 클래식 fold
또는 reduce
기능의 한주기입니다 .
@azium이 state -> action -> state
.
앱의 일련의 작업이 목록과 같거나 스트림과 비슷하다고 생각하면 더 합리적 일 수 있습니다.
이 인위적인 예를 보자 :
['apple', 'banana', 'cherry'].reduce((acc, item) => acc + item.length, 0)
첫 번째 인수는 형식의 함수입니다 (Int, String) => Int
. 초기 값과 함께 reduce
"리듀서 함수"라고하는 것을 전달 하고 일련의 항목을 처리 한 결과를 얻습니다. 따라서 감속기 기능은 결과를 변경하기 위해 연속적인 개별 항목에 대해 수행되는 작업을 설명합니다. 즉, 감속기 함수는 이전 출력과 다음 값을 취하고 다음 출력을 계산합니다.
이것은 Redux 감속기가 수행하는 작업과 유사합니다. 이전 상태와 현재 작업을 취하고 다음 상태를 계산합니다.
진정한 함수형 프로그래밍 스타일에서는 인수와 결과에 적용된 의미를 개념적으로 지우고 입력 및 출력의 "모양"에만 집중할 수 있습니다.
실제로 Redux 감속기는 일반적으로 주어진 작업에 대해 모두 동일한 속성을 변경하지 않으므로 책임을 분할하고 출력을 combineReducers
.
redux 감속기 가 a라고 불리는 이유 는 결과를 얻기 위해 이러한 작업을 수행 할
reducer
acollection of actions
와initial state
(저장소)를 "줄일"수 있기 때문final state
입니다.
어떻게? 이에 답하기 위해 감속기를 다시 정의하겠습니다.
감소 () 메소드는 적용
function (reducer)
대해accumulator
상기 어레이의 각각의 값 (의 왼쪽에서 오른쪽으로) 하나의 값으로 감소시키기 위해.
그리고 redux 감속기는 무엇을합니까?
감속기는
function
현재 상태와 동작을 취하고 다음 상태를 반환 하는 순수 입니다. 상태는accumulated
컬렉션에 대한 각 작업이이 상태를 변경하기 위해 적용되는 것과 같습니다.
따라서가 주어지면 collection of actions
감속기가 컬렉션의 각 값 (왼쪽에서 오른쪽으로)에 적용됩니다. 처음에는 initial value
. 이제 감속기가이 초기 상태와 다음 상태를 반환하는 첫 번째 동작에 다시 적용됩니다. 그리고 다음 컬렉션 항목 (작업)은 배열의 끝에 도달 할 때까지 current state
가져 오기 위해 매번 적용 next state
됩니다. 그런 다음 the final state
. 얼마나 멋진가요!
저자는 상태를 감소 기능의 누산기로 생각합니다. 전의:
Final State = [Action1, Action2, ..., ActionN].reduce(reducer, Initial State);
reduce 기능은 Functional Programming에서 나왔고 "reducer"라는 이름도 FP에서 나왔습니다.
나는 여기에서 그 이름을 사용하는 것을 좋아하지 않습니다. 나는 세상을 행동 후 하나의 가치 결과로 보지 않기 때문입니다. 여기서 상태는 객체입니다. 예를 들면 :
['eat', 'sleep'] === [addTodo('eat'), addTodo('sleep')].reduce(reducer, []);
이 감속기는 전혀 감소하지 않습니다. 그리고 나는 그것이 아무것도 줄이든 말든 상관하지 않습니다. Transducer 로 이름을 지정하는 것이 더 합리적입니다.
이제 부터는 Deducer 라고 부를 까요 ? 이전 상태와 들어오는 작업을 기반으로 새로운 상태를 추론합니다.
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));
다른 답변은 이름이있는 이유를 잘 설명하지만 더 많은 이름을 지정해 보겠습니다.
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 와도 비슷합니다.
아래 코드에서는 누산기를 작업으로, 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 () 메서드는 배열의 각 요소에 대해 사용자가 제공하는 감속기 함수를 실행하여 단일 출력 값을 생성합니다.
reduce
기본값과 다른 값에 액세스 할 수 있고 잠재적으로 변환 된 기본값을 다시 제공하는에 전달하는 함수처럼 동작하기 때문에 정확히 감속기 입니다.state -> action -> state