实现 redux 中 action.type 按照组件分类实现模块化,解决不同组件下 types 的命名冲突。
这里提供两种方案:
项目目录结构
.
├── App.jsx
├── axios
│ └── axios.js
├── components
│ ├── effect
│ │ ├── reducer.js //定义组件的 reducer
│ │ ├── saga.js //集中处理组件的副作用操作
│ │ ├── server.js //集中定义组件的 api fetch
│ │ ├── types.js //集中定义组件的 action.types变量
│ │ └── view.jsx //组件入口文件
│ ├── home
│ │ ├── reducer.js
│ │ ├── saga.js
│ │ ├── types.js
│ │ └── view.jsx
│ ├── list
│ │ ├── reducer.js
│ │ ├── saga.js
│ │ ├── types.js
│ │ └── view.jsx
│ ├── reducer.js
│ ├── saga.js
│ └── types.js
├── entry.jsx
└── store
├── reducer.js
├── saga.js
└── store.js
第一种方案:利用 Symbol 定义 types
//types.js
export let fetchSucceed = Symbol('fetchSucceed');
export let fetchFailed = Symbol('fetchFailed');
export let fetchCategories = Symbol('fetchCategories');
export let waitChangeAsync = Symbol('waitChangeAsync');
在 reducer.js 中使用
//reducer.js
import * as types from './types'
const defaultState = {
data: []
}
const reducer = (state = defaultState, action) => {
switch (action.type) {
case types.fetchSucceed:
return Object.assign({}, {
data: action.data
});
case types.fetchFailed:
return Object.assign({}, {
data: action.data
});
default:
return state;
}
}
export default reducer;
第二种方案:使用react-redux-types-loader
在 webpack 中配置 loader
module:{
rules:[{
test: /component\/([^/]+\/)*type[s]?.js$/,
exclude: /node_modules/,
loaders: ['react-redux-types-loader'],
}]
}
types.js的使用方式和第一种方案一样,loader 会改写文件源码,转化为 "文件路径+变量名"的字符串,可在chrome redux-devtools 中查看到。
export let fetchSucceed; //=> "/src/components/effect/fetchSucceed"
export let fetchFailed;
export let fetchCategories;
export let waitChangeAsync;
//或者
export let a,b,c;
//或者
export const a = 'aaa';
export const b = 'bbb';
export let c = 'ccc';