我是redux架构的新手,我有这个基本的疑问,我们可以在使用combinedReducer和createStore方法创建商店后更新reducers列表吗?
答案 0 :(得分:1)
是的,您可以使用Redux store
的{{3}} api异步更新Reducer并注入一个新的。
为例这是一个高级API。如果您的应用程序实现代码,您可能需要此 拆分,并且您想要动态加载一些Reducer。您 如果你实现了一个热重载机制,也可能需要这个 终极版。
在starter-kit中,作为reducers
方法的参数传递的createStore
是makeRootReducers()
的结果。注意没有一个异步缩减器被传递给这个函数。
// extract of src/store/createStore.js
import { applyMiddleware, compose, createStore } from 'redux'
import { routerMiddleware } from 'react-router-redux'
import thunk from 'redux-thunk'
import makeRootReducer from './reducers'
export default (initialState = {}, history) => {
// ...
// ======================================================
// Store Instantiation and HMR Setup
// ======================================================
const store = createStore(
makeRootReducer(), // <------------- without arguments, it returns only the synchronously reducers
initialState,
compose(
applyMiddleware(...middleware),
...enhancers
)
)
store.asyncReducers = {}
// ...
}
makeRootReducer
函数使用默认的reducers调用combineReducers
启动所需的(如router
reducer)和其他“异步”reducers作为参数传递injectReducer
是一个在运行时注入新reducers的函数。它在商店中调用replaceReducer
api作为参数通过makeRootReducer(async)
函数获取新的reducer列表见下文:
// src/store/reducers.js
import { combineReducers } from 'redux'
import { routerReducer as router } from 'react-router-redux'
export const makeRootReducer = (asyncReducers) => {
return combineReducers({
// Add sync reducers here
router,
...asyncReducers
})
}
export const injectReducer = (store, { key, reducer }) => {
store.asyncReducers[key] = reducer
store.replaceReducer(makeRootReducer(store.asyncReducers))
}
export default makeRootReducer
最后,在starter-kit中,reducer被注入路由定义,如下所示:
// src/routes/Counter/index.js
import { injectReducer } from '../../store/reducers'
export default (store) => ({
path: 'counter',
/* Async getComponent is only invoked when route matches */
getComponent (nextState, cb) {
/* Webpack - use 'require.ensure' to create a split point
and embed an async module loader (jsonp) when bundling */
require.ensure([], (require) => {
/* Webpack - use require callback to define
dependencies for bundling */
const Counter = require('./containers/CounterContainer').default
const reducer = require('./modules/counter').default
/* ----> HERE <---- */
/* Add the reducer to the store on key 'counter' */
injectReducer(store, { key: 'counter', reducer }) // <-------
/* Return getComponent */
cb(null, Counter)
/* Webpack named bundle */
}, 'counter')
}
当您想要拆分大型应用程序并避免在启动时加载所有Reducer时,此技术很有用。