上一篇文章主要说了 redux 的简单用法,为了和后续 umi 体系进行对齐,增加一篇 redux 有多个 reducer,并且合并的情况用法。
最终代码可以看这里 github
很多项目都是按模块化区分的,对于不同的模块理应 reducer 也是分开的。最终导出的 reducer 在进行合并。
首先参考上次的代码,来进行修改调整。
index.js
文件完全相同,不需要修改。
reducer.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| + import { combineReducers } from "redux";
const globalReducer = (state = { count: 10 }, action) => { switch (action.type) { case "INCREMENT": return { ...state, count: state.count + action.payload } case "DECREMENT": return { ...state, count: state.count - action.payload } default: return state } }
+ const otherReducer = (state = { count: 20 }, action) => { + switch (action.type) { + case "CLEAR": + return { ...state, count: 0 } + case "TOMAX": + return { ...state, count: 100 } + default: + return state + } + }
- export default globalReducer + export default combineReducers({ + globalReducer, + otherReducer + })
|
我们增加一个 otherReducer
,最后使用 combineReducers
进行合并。为了省事,我把两个 reducer 写到一个文件里了,实际项目更可能是分布在两个文件中。
combineReducers
里的对象默认是如下形式:
1 2 3 4
| { globalReducer: globalReducer, otherReducer: otherReducer }
|
当然你可以改名为:
1 2 3 4
| { aaa: globalReducer, bbb: otherReducer }
|
后续获取全局 state
时候就要换成自定义的字段名。
Counter.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import React from "react" import { connect } from "react-redux"
class Counter extends React.PureComponent { render () { - const { globalState, dispatch } = this.props + const { globalState, otherState, dispatch } = this.props return ( <div> <p>COUNT:{globalState.count}</p> <button onClick={() => dispatch({ type: "INCREMENT", payload: 1 })}> +1 </button> <button onClick={() => dispatch({ type: "DECREMENT", payload: 1 })}> -1 </button> + <p>COUNT:{otherState.count}</p> + <button onClick={() => dispatch({ type: "CLEAR" })}> + clear + </button> + <button onClick={() => dispatch({ type: "TOMAX" })}> + to max + </button> </div> ) } }
const mapStateToProps = state => { - return ({ globalState: state }) + return ({ globalState: state.globalReducer, otherState: state.otherReducer }) } export default connect(mapStateToProps)(Counter)
|
为了省事,我把这个组件增加了两个按钮功能,实际情况更可能是另外一个组件来调用对应的方法。
与之前不同的是,全局 state
不再是一层对象了,而是被我们 reducer 定义的字段名包了一层。
需要注意的是,我们调用 dispatch({ type: "DECREMENT", payload: 1 })
后,不仅 globalReducer
会被执行,otherReducer
也会被执行。只不过 otherReducer
走到了 default
情况。这也就是 reducer 不要写带有副作用的功能!
–END–