【发布时间】:2016-07-03 09:20:31
【问题描述】:
我是 redux 架构的新手,我有一个基本的疑问,我们可以在使用 combineReducer 和 createStore 方法创建商店后更新减速器列表吗?
【问题讨论】:
标签: redux react-redux reducers
我是 redux 架构的新手,我有一个基本的疑问,我们可以在使用 combineReducer 和 createStore 方法创建商店后更新减速器列表吗?
【问题讨论】:
标签: redux react-redux reducers
是的,您可以使用 Redux store 的 replaceReducer api 更新 reducer 并异步注入一个新的。
这是一个高级 API。如果您的应用程序实现代码,您可能需要这个 拆分,并且您想动态加载一些减速器。你 如果您为 还原。
以starter-kit为例
在createStore.js file 中,作为参数传递给createStore 方法的reducers 是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 函数调用 combineReducers 使用默认减速器
启动所需的(如routerreducer)和其他作为参数传递的“异步”reducerinjectReducer 是一个函数,用于在运行时注入新的 reducer。它在 store 上调用 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')
}
当您想要拆分大型应用程序并避免在启动时加载所有减速器时,此技术很有用。
【讨论】: