使用反应路由器 4 动态加载 redux 减速器 [英] Dynamically load redux reducers with react router 4

查看:56
本文介绍了使用反应路由器 4 动态加载 redux 减速器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在根据组件拆分我的代码,并且我只想在组件加载时注入我的减速器,而不是从一开始就在商店中将它们全部堆叠起来.

I'm splitting my code based on components and I want to inject my reducers only when a component loads, rather than stacking them all up from the start in the store.

在反应路由器 3 中,它非常简单,但我似乎无法让它与反应路由器 4 一起使用.

In react router 3 it was pretty straight forward but I can't seem to get it to work with react router 4.

这是减速器和商店:

reducers.js

reducers.js

import { combineReducers } from 'redux'
import { routerReducer } from 'react-router-redux'

import modalReducer from '../modules/modal'

export default combineReducers({
  routing : routerReducer,
  modal   : modalReducer
})

store.js

import { createStore, applyMiddleware, compose } from 'redux'
import { routerMiddleware } from 'react-router-redux'
import thunk from 'redux-thunk'
import createHistory from 'history/createBrowserHistory'
import rootReducer from './reducers'

export const history = createHistory()

const initialState = {}
const enhancers = []
const middleware = [
  thunk,
  routerMiddleware(history)
]

if (process.env.NODE_ENV === 'development') {
  const devToolsExtension = window.devToolsExtension

  if (typeof devToolsExtension === 'function') {
    enhancers.push(devToolsExtension())
  }
}

const composedEnhancers = compose(
  applyMiddleware(...middleware),
  ...enhancers
)

const store = createStore(
  rootReducer(),
  initialState,
  composedEnhancers
)
export default store

我对路由使用了延迟加载.

And I'm using lazy load for the routes.

如何实现拆分减速器?

我想像这样注入异步减速器:

I would like to inject the async reducers something like so:

function createReducer(asyncReducers) {
  return combineReducers({
    ...asyncReducers,
    system,
    router,
  })
}

function injectReducer(store, { key, reducer }) {
  if (Reflect.has(store.asyncReducers, key)) return

  store.asyncReducers[key] = reducer
  store.replaceReducer(createReducer(store.asyncReducers))
}

推荐答案

react-router v4 中,对于减速器的异步注入,请执行以下操作:

In react-router v4, for async injection of reducers, do the following:

在您的 reducer.js 文件中添加一个名为 createReducer 的函数,该函数将注入的 Reducer 作为 arg 并返回组合的 reducer:

In your reducer.js file add a function called createReducer that takes in the injectedReducers as arg and returns the combined reducer:

/**
 * Creates the main reducer with the dynamically injected ones
 */
export default function createReducer(injectedReducers) {
  return combineReducers({
    route: routeReducer,
    modal: modalReducer,
    ...injectedReducers,
  });
} 

然后,在您的 store.js 文件中,

Then, in your store.js file,

import createReducer from './reducers.js';

const store = createStore(
  createReducer(),
  initialState,
  composedEnhancers
);
store.injectedReducers = {}; // Reducer registry

现在,为了在 React 容器挂载时以异步方式注入 reducer,您需要使用 injectReducer.js 在你的容器中运行,然后将所有的 reducer 与 connect 组合起来.示例组件 Todo.js:

Now, in order to inject reducer in an async manner when your react container mounts, you need to use the injectReducer.js function in your container and then compose all the reducers along with connect. Example component Todo.js:

// example component 
import { connect } from 'react-redux';
import { compose } from 'redux';
import injectReducer from 'filepath/injectReducer';
import { addToDo, starToDo } from 'containers/Todo/reducer';

class Todo extends React.Component {
// your component code here
}
const withConnect = connect(mapStateToProps, mapDispatchToProps);

const addToDoReducer = injectReducer({
  key: 'todoList',
  reducer: addToDo,
});

const starToDoReducer = injectReducer({
  key: 'starredToDoList',
  reducer: starToDo,
});

export default compose(
  addToDoReducer,
  starToDoReducer,
  withConnect,
)(Todo);

React-Boilerplate 是了解整个设置的绝佳来源.您可以生成在几秒钟内完成一个示例应用程序.用于injectReducer.js、configureStore.js(或你的例子中的store.js)的代码,实际上整个配置都可以从react-boilerplate 中获取.可以在此处找到 injectReducer.js<的特定链接/a>、configureStore.js.

React-Boilerplate is an excellent source for understanding this whole setup.You can generate a sample app within seconds. The code for injectReducer.js, configureStore.js( or store.js in your case) and in fact this whole configuration can be taken from react-boilerplate. Specific link can be found here for injectReducer.js, configureStore.js.

这篇关于使用反应路由器 4 动态加载 redux 减速器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆