답변
TL; DR
combineReducers()수동 코드 없이 또는 유사한 수동 코드 는 감속기에 전달 된 것이 이고 그렇지 않기 때문에initialState항상state = ...감속기에서 승리 하므로이 경우 ES6 인수 구문이 적용되지 않습니다.stateinitialStateundefined로
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인수 로 호출 될 때 감속기에서 초기 상태를 반환하면 (이를 구현하는 가장 쉬운 방법은 stateES6 기본 인수 값 을 지정하는 것입니다), 결합 된 감속기에 대한 유용한 동작입니다. 그들은 함수에 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 ) {
....
}
}
}
답변
