【问题标题】:update redux reducers after store initialization在 store 初始化后更新 redux reducer
【发布时间】:2016-07-03 09:20:31
【问题描述】:

我是 redux 架构的新手,我有一个基本的疑问,我们可以在使用 combineReducer 和 createStore 方法创建商店后更新减速器列表吗?

【问题讨论】:

    标签: redux react-redux reducers


    【解决方案1】:

    是的,您可以使用 Redux storereplaceReducer api 更新 reducer 并异步注入一个新的。

    这是一个高级 API。如果您的应用程序实现代码,您可能需要这个 拆分,并且您想动态加载一些减速器。你 如果您为 还原。

    starter-kit为例

    createStore.js file 中,作为参数传递给createStore 方法的reducersmakeRootReducers() 的结果。注意没有一个异步减速器被传递给这个函数。

     // 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 = {}
    
      // ...
      }
    

    reducers.js file:

    • makeRootReducer 函数调用 combineReducers 使用默认减速器 启动所需的(如routerreducer)和其他作为参数传递的“异步”reducer
    • injectReducer 是一个函数,用于在运行时注入新的 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')
      }
    

    当您想要拆分大型应用程序并避免在启动时加载所有减速器时,此技术很有用。

    【讨论】:

    • 感谢您的解决方案,它解决了问题。
    • @Sibeshkumar 很高兴能帮到你!
    猜你喜欢
    • 2018-09-27
    • 2016-02-18
    • 2018-08-09
    • 2020-10-21
    • 1970-01-01
    • 2017-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多