답변
TL; DR
combineReducers()
수동 코드 없이 또는 유사한 수동 코드 는 감속기에 전달 된 것이 이고 그렇지 않기 때문에initialState
항상state = ...
감속기에서 승리 하므로이 경우 ES6 인수 구문이 적용되지 않습니다.state
initialState
undefined
로
combineReducers()
동작 미묘한 차이입니다. 그 상태로 지정되어 그 감속기는initialState
그를 받게됩니다state
. 다른 감속기는 수신undefined
하고 그 때문에 지정된state = ...
기본 인수로 돌아갑니다 .일반적으로
initialState
감속기에서 지정한 상태보다 우선합니다. 이를 통해 리듀서 는 기본 인수로 이해할 수있는 초기 데이터를 지정할 수 있지만 일부 영구 저장소 또는 서버에서 저장소를 수화 할 때 기존 데이터 (전체 또는 부분)를로드 할 수도 있습니다.
먼저 감속기가 하나 인 경우를 고려해 봅시다.
사용하지 않는 말 combineReducers()
.
그러면 감속기가 다음과 같이 보일 수 있습니다.
function counter(state = 0, action) {
switch (action.type) {
case 'INCREMENT': return state + 1;
case 'DECREMENT': return state - 1;
default: return state;
}
}
이제 상점을 만든다고 가정 해 봅시다.
import { createStore } from 'redux';
let store = createStore(counter);
console.log(store.getState()); // 0
초기 상태는 0입니다. 왜? 에 대한 두 번째 인수 createStore
는 undefined
. 이것은 state
처음으로 감속기에 전달됩니다. Redux가 초기화 될 때 상태를 채우기 위해 “더미”액션을 전달합니다. 그래서 counter
감속기가 호출되었습니다 state
동일 undefined
. 이것은 기본 인수를 “활성화”하는 경우입니다. 따라서 state
이제 0
기본값 state
( state = 0
)을 따릅니다. 이 상태 ( 0
)가 반환됩니다.
다른 시나리오를 고려해 보겠습니다.
import { createStore } from 'redux';
let store = createStore(counter, 42);
console.log(store.getState()); // 42
이번이 42
아닌 이유는 무엇 0
입니까? 두 번째 인수로 createStore
와 함께 호출 되었기 42
때문입니다. 이 인수는 state
더미 작업과 함께 감속기에 전달됩니다. 이번에 state
는 정의되지 않았으므로 ( 42
!) ES6 기본 인수 구문은 효과가 없습니다. 는 state
이다 42
, 및 42
감속기에서 반환됩니다.
이제 사용하는 경우를 고려해 봅시다 combineReducers()
.
두 개의 감속기가 있습니다.
function a(state = 'lol', action) {
return state;
}
function b(state = 'wat', action) {
return state;
}
에 의해 생성 된 감속기는 combineReducers({ a, b })
다음과 같습니다.
// const combined = combineReducers({ a, b })
function combined(state = {}, action) {
return {
a: a(state.a, action),
b: b(state.b, action)
};
}
createStore
없이 호출하면 initialState
로 초기화 state
됩니다 {}
. 따라서, state.a
그리고 state.b
될 것입니다 undefined
그것을 호출하는 시간 a
및 b
감속기. 모두 a
와 b
감속기 받게됩니다 undefined
로 자신의 state
주장, 그들은 기본 지정하면 state
값을, 그 반환됩니다. 이것이 결합 된 감속기가 { a: 'lol', b: 'wat' }
첫 번째 호출에서 상태 객체를 반환하는 방법 입니다.
import { createStore } from 'redux';
let store = createStore(combined);
console.log(store.getState()); // { a: 'lol', b: 'wat' }
다른 시나리오를 고려해 보겠습니다.
import { createStore } from 'redux';
let store = createStore(combined, { a: 'horse' });
console.log(store.getState()); // { a: 'horse', b: 'wat' }
이제를 initialState
인수로 지정 했습니다 createStore()
. 결합 된 감속기에서 반환 된 상태는 감속기에 대해 지정한 초기 상태 를 감속기에 지정된 기본 인수 와 결합 합니다 .a
'wat'
b
결합 된 감속기가 무엇을하는지 생각해 봅시다.
// const combined = combineReducers({ a, b })
function combined(state = {}, action) {
return {
a: a(state.a, action),
b: b(state.b, action)
};
}
이 경우는 state
로 돌아 가지 않도록 지정되었습니다 {}
. a
필드가 'horse'
와 같지만 필드 가없는 개체였습니다 b
. 이것이 a
감속기 'horse'
가 그것의 것으로 state
받고 기꺼이 그것을 반환 한 이유입니다. 그러나 b
감속기는 undefined
그것으로 받아 들여서 기본값에 대한 아이디어 를 state
반환 했습니다state
(이 예에서는 'wat'
). 이것이 우리가 { a: 'horse', b: 'wat' }
대가로 얻는 방법 입니다.
요약하자면, Redux 규칙을 고수 undefined
하고 state
인수 로 호출 될 때 감속기에서 초기 상태를 반환하면 (이를 구현하는 가장 쉬운 방법은 state
ES6 기본 인수 값 을 지정하는 것입니다), 결합 된 감속기에 대한 유용한 동작입니다. 그들은 함수에 initialState
전달 하는 객체 의 해당 값을 선호 createStore()
하지만 전달하지 않았거나 해당 필드가 설정되지 않은 state
경우 감속기에 지정된 기본 인수가 대신 선택됩니다.이 접근 방식은 기존 데이터의 초기화와 수화를 모두 제공하기 때문에 잘 작동하지만 데이터가 보존되지 않은 경우 개별 감속기가 상태를 재설정 할 수 있습니다. 물론 combineReducers()
여러 레벨에서 사용할 수 있으므로이 패턴을 재귀 적으로 적용 하거나 리듀서를 호출하고 상태 트리의 관련 부분을 제공하여 리듀서를 수동으로 구성 할 수도 있습니다 .
답변
간단히 말해서, 초기 상태를 감속기에 전달하는 사람은 Redux이므로 아무것도 할 필요가 없습니다.
전화를 걸면 createStore(reducer, [initialState])
Redux에게 첫 번째 작업이 들어올 때 감속기에 전달되는 초기 상태가 무엇인지 알려주는 것입니다.
두 번째 옵션은 스토어를 생성 할 때 초기 상태를 통과하지 못한 경우에만 적용됩니다. 즉
function todoApp(state = initialState, action)
상태는 Redux에 의해 전달 된 상태가없는 경우에만 초기화됩니다.
답변
저장소에서 그 상태를 어떻게 읽고 감속기의 첫 번째 인수로 만들까요?
combineReducers ()가 당신을 위해 일합니다. 작성하는 첫 번째 방법은별로 도움이되지 않습니다.
const rootReducer = combineReducers({ todos, users })
그러나 다른 하나는 동등합니다.
function rootReducer(state, action) {
todos: todos(state.todos, action),
users: users(state.users, action)
}
답변
이것이 귀하의 요청에 응답하기를 바랍니다 (intialState를 전달하고 해당 상태를 반환하는 동안 감속기를 초기화하는 것으로 이해했습니다)
이것이 우리가하는 방법입니다 (경고 : Typescript 코드에서 복사).
요점은 if(!state)
mainReducer (factory) 함수 의 테스트입니다.
function getInitialState(): MainState {
return {
prop1: 'value1',
prop1: 'value2',
...
}
}
const reducer = combineReducers(
{
main: mainReducer( getInitialState() ),
...
}
)
const mainReducer = ( initialState: MainState ): Reducer => {
return ( state: MainState, action: Action ): MainState => {
if ( !state ) {
return initialState
}
console.log( 'Main reducer action: ', action )
switch ( action.type ) {
....
}
}
}