Redux 앱의 초기 상태는 두 가지 방법으로 설정할 수 있습니다.
초기 상태를 저장소에 전달하는 경우 저장소에서 해당 상태를 어떻게 읽고 감속기의 첫 번째 인수로 만들까요?
답변:
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()
여러 레벨에서 사용할 수 있으므로이 패턴을 재귀 적으로 적용 하거나 리듀서를 호출하고 상태 트리의 관련 부분을 제공하여 리듀서를 수동으로 구성 할 수도 있습니다 .
function counter(state = 0, action)
또는 function visibleIds(state = [], action)
.
간단히 말해서, 초기 상태를 감속기에 전달하는 사람은 Redux이므로 아무것도 할 필요가 없습니다.
전화를 걸면 createStore(reducer, [initialState])
Redux에게 첫 번째 작업이 들어올 때 감속기에 전달되는 초기 상태가 무엇인지 알려주는 것입니다.
두 번째 옵션은 스토어를 생성 할 때 초기 상태를 통과하지 못한 경우에만 적용됩니다. 즉
function todoApp(state = initialState, action)
상태는 Redux에 의해 전달 된 상태가없는 경우에만 초기화됩니다.
menuState
들어가있는 경우 메뉴 리듀서에게 state.menu
상점에서의 값을 읽고 초기 상태로 사용하도록 어떻게 지시 합니까?
이것이 귀하의 요청에 응답하기를 바랍니다 (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 ) {
....
}
}
}
combineReducers
. 다시 한번 감사드립니다.