Redux createStore()의 처리를 쫓는다(Middleware 있는 경우)
이전 기사 에서는, 「Middleware를 사용하지 않는 경우」를 썼습니다. 이 기사에서는 "Middleware를 사용하는 경우"를 씁니다.
이 기사에서 설명하는 흐름은 호출자가 이런 식으로 호출하는 경우를 가정합니다.
index.js
// stateの初期状態無し
let store = createStore(reducerA, applyMiddleware(
middlewareA,
middlewareB
));
// stateの初期状態あり
let store = createStore(reducerA, preloadedState, applyMiddleware(
middlewareA,
middlewareB
));
applyMiddleware의 첫 번째 단계
먼저 applyMiddleware.js 의 applyMiddleware()를 호출합니다. 이 함수는 "함수를 반환하는 함수"이므로 함수를 반환합니다.
applyMiddleware.jsexport default function applyMiddleware(...middlewares) {
return createStore => (...args) => {
}
}
applyMiddleware()가 반환하는 함수는 "createStore를 인수로 취하고 "...args를 인수로 취하여 무엇인가를 반환하는 함수"를 반환하는 함수입니다. 일본어로하면 다소 어렵습니다. 이 편을 잘 표현하는 좋은 방법은 없습니까?
createStore() 처리
reducer와 applyMiddleware()로 만든 함수(=enhancer)가 createStore()에 들어옵니다.
인수의 정리와 형태 체크와 enhancer의 실행
여기에서는 조금 「딥 냄새」, 인수의 체크와 교환을 실시하고 있습니다.
createStore()의 인수 중 preloadedState와 enhancer는 생략되었을 수 있습니다. preloadedState가 생략되고 enhancer가있는 경우, preloadedState의 위치에 enhancer가 포함되어 있기 때문에 이것을 바꿉니다.
마지막으로 enhancer를 호출하고 결과를 반환합니다.
createStore.jsexport default function createStore(reducer, preloadedState, enhancer) {
if (
(typeof preloadedState === 'function' && typeof enhancer === 'function') ||
(typeof enhancer === 'function' && typeof arguments[3] === 'function')
) {
throw new Error(
'It looks like you are passing several store enhancers to ' +
'createStore(). This is not supported. Instead, compose them ' +
'together to a single function'
)
}
if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
enhancer = preloadedState
preloadedState = undefined
}
if (typeof enhancer !== 'undefined') {
if (typeof enhancer !== 'function') {
throw new Error('Expected the enhancer to be a function.')
}
return enhancer(createStore)(reducer, preloadedState)
}
enhancer(createState)의 처리 내용
enhancer는 applyMiddleware()의 반환값인 함수입니다.
applyMiddleware.jsexport default function applyMiddleware(...middlewares) {
return createStore => (...args) => {
↑ 중, enhancer는 "createStore => (...args) => {}"부분, createStore는 createStore 부분, reducer와 preloadedState는 ...args 부분에 대응하고 있습니다.
createState는 호출자로부터 건너온 변수이지만 대본에서는 createState.js의 createState() 함수를 지정하고 있습니다.enhancer(createState)
는 결과적으로 "...args를 인수로 취해 무언가를 반환하는 함수"를 반환하고 있습니다.
enhancer (createStore) (reducer, preloadedState)의 처리 내용
여기에서는 Store 오브젝트의 생성과, Middleware의 초기화(?)와 체인을 작성해, Store 오브젝트의 dispatch 함수를 덧쓰기한 것을 돌려줍니다.
applyMiddleware.js const store = createStore(...args)
let dispatch = () => {
throw new Error(
`Dispatching while constructing your middleware is not allowed. ` +
`Other middleware would not be applied to this dispatch.`
)
}
const middlewareAPI = {
getState: store.getState,
dispatch: (...args) => dispatch(...args)
}
const chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch
}
우선 const store = createStore(...args)
로 store 오브젝트가 생성됩니다. 여기서 ..args는 호출자의 reducer, preloadedState이므로 Redux의 createStore() 처리를 추구한다(Middleware를 사용하지 않는 경우)의 처리로 들어갑니다.
흥미롭게도 첫 번째 디스패치에는 "오류를 날리는 함수"가 할당되었습니다. 체인을 만든 후 체인을 만든 후 그 시작을 dispatch로 덮어 씁니다.
이 근처 불필요하지 않을까? 라고는 생각합니다만, 뭔가 이유가 있을 것 같습니다. 또 다른 기회에 조사하려고 합니다.
또, dispatch = compose(...chain)(store.dispatch)
여기의 이해도 힘들었습니다. 결과적으로는 「action을 받아 next(action)로 다음에 건너가는 함수의 체인」이 완성됩니다만, compose와 Middleware의 쓰는 방법 양쪽으로 어떻게 움직이는지를 이해하는 데 시간이 걸렸습니다. 이 엔도 그 중 다른 기사로 쓰고 싶습니다.
마지막 return입니다만, store 오브젝트의 각 요소를 전개한 다음에, dispatch 는 다른 것에 재기입하고 있습니다. 이것에 의해, store.dispatch()의 재로, 우선 Middleware층이 움직여, 그 후에 createStore()로 생성된 dispatch 함수에 도착하게 됩니다.
이 retuen로 돌려주어지는 store 오브젝트가, 호출원까지 돌아갑니다.
결과 어떤 형태의 객체가 생성되는지
createStore()로 생성되는 store 객체 중 dispatch 함수가 applyMiddleware로 조립된 체인의 선두로 바뀝니다.
applyMiddleware는 각 Middleware 안에서 next(action)를 호출하고 다음에 가지만, 마지막으로 createStore()로 생성되는 dispatch에 도착합니다.
Reference
이 문제에 관하여(Redux createStore()의 처리를 쫓는다(Middleware 있는 경우)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/paming/items/0f660a382aae2125818c
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
export default function applyMiddleware(...middlewares) {
return createStore => (...args) => {
}
}
reducer와 applyMiddleware()로 만든 함수(=enhancer)가 createStore()에 들어옵니다.
인수의 정리와 형태 체크와 enhancer의 실행
여기에서는 조금 「딥 냄새」, 인수의 체크와 교환을 실시하고 있습니다.
createStore()의 인수 중 preloadedState와 enhancer는 생략되었을 수 있습니다. preloadedState가 생략되고 enhancer가있는 경우, preloadedState의 위치에 enhancer가 포함되어 있기 때문에 이것을 바꿉니다.
마지막으로 enhancer를 호출하고 결과를 반환합니다.
createStore.js
export default function createStore(reducer, preloadedState, enhancer) {
if (
(typeof preloadedState === 'function' && typeof enhancer === 'function') ||
(typeof enhancer === 'function' && typeof arguments[3] === 'function')
) {
throw new Error(
'It looks like you are passing several store enhancers to ' +
'createStore(). This is not supported. Instead, compose them ' +
'together to a single function'
)
}
if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
enhancer = preloadedState
preloadedState = undefined
}
if (typeof enhancer !== 'undefined') {
if (typeof enhancer !== 'function') {
throw new Error('Expected the enhancer to be a function.')
}
return enhancer(createStore)(reducer, preloadedState)
}
enhancer(createState)의 처리 내용
enhancer는 applyMiddleware()의 반환값인 함수입니다.
applyMiddleware.js
export default function applyMiddleware(...middlewares) {
return createStore => (...args) => {
↑ 중, enhancer는 "createStore => (...args) => {}"부분, createStore는 createStore 부분, reducer와 preloadedState는 ...args 부분에 대응하고 있습니다.
createState는 호출자로부터 건너온 변수이지만 대본에서는 createState.js의 createState() 함수를 지정하고 있습니다.
enhancer(createState)
는 결과적으로 "...args를 인수로 취해 무언가를 반환하는 함수"를 반환하고 있습니다.enhancer (createStore) (reducer, preloadedState)의 처리 내용
여기에서는 Store 오브젝트의 생성과, Middleware의 초기화(?)와 체인을 작성해, Store 오브젝트의 dispatch 함수를 덧쓰기한 것을 돌려줍니다.
applyMiddleware.js
const store = createStore(...args)
let dispatch = () => {
throw new Error(
`Dispatching while constructing your middleware is not allowed. ` +
`Other middleware would not be applied to this dispatch.`
)
}
const middlewareAPI = {
getState: store.getState,
dispatch: (...args) => dispatch(...args)
}
const chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch
}
우선
const store = createStore(...args)
로 store 오브젝트가 생성됩니다. 여기서 ..args는 호출자의 reducer, preloadedState이므로 Redux의 createStore() 처리를 추구한다(Middleware를 사용하지 않는 경우)의 처리로 들어갑니다.흥미롭게도 첫 번째 디스패치에는 "오류를 날리는 함수"가 할당되었습니다. 체인을 만든 후 체인을 만든 후 그 시작을 dispatch로 덮어 씁니다.
이 근처 불필요하지 않을까? 라고는 생각합니다만, 뭔가 이유가 있을 것 같습니다. 또 다른 기회에 조사하려고 합니다.
또,
dispatch = compose(...chain)(store.dispatch)
여기의 이해도 힘들었습니다. 결과적으로는 「action을 받아 next(action)로 다음에 건너가는 함수의 체인」이 완성됩니다만, compose와 Middleware의 쓰는 방법 양쪽으로 어떻게 움직이는지를 이해하는 데 시간이 걸렸습니다. 이 엔도 그 중 다른 기사로 쓰고 싶습니다.마지막 return입니다만, store 오브젝트의 각 요소를 전개한 다음에, dispatch 는 다른 것에 재기입하고 있습니다. 이것에 의해, store.dispatch()의 재로, 우선 Middleware층이 움직여, 그 후에 createStore()로 생성된 dispatch 함수에 도착하게 됩니다.
이 retuen로 돌려주어지는 store 오브젝트가, 호출원까지 돌아갑니다.
결과 어떤 형태의 객체가 생성되는지
createStore()로 생성되는 store 객체 중 dispatch 함수가 applyMiddleware로 조립된 체인의 선두로 바뀝니다.
applyMiddleware는 각 Middleware 안에서 next(action)를 호출하고 다음에 가지만, 마지막으로 createStore()로 생성되는 dispatch에 도착합니다.
Reference
이 문제에 관하여(Redux createStore()의 처리를 쫓는다(Middleware 있는 경우)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/paming/items/0f660a382aae2125818c
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(Redux createStore()의 처리를 쫓는다(Middleware 있는 경우)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/paming/items/0f660a382aae2125818c텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)