前言
公司中台我的项目应用 redux 进行状态治理,家喻户晓,redux 写起来就是在节约生命。但鉴于我的项目重构老本太大,因而决定先在不扭转框架的状况下,在原先代码的根底上一步步优化简化 redux 用法。
优化
先来看看原来的文件目录构造:
├── store│ └── modules│ ├── todoList│ │ ├── todoList_action.js│ │ ├── todoList_reducer.js│ │ ├── todoList_state.js│ │ └── todoList_types.js
页面代码:
// todoList_types.jsexport const types = { TODO_LIST: "TODO_LIST",};
// todoList_action.jsimport types from "./todoList_types";// 接口import { todoListSvr } from "services/card";// 应用了 thunkMiddleware 中间件export const todoList = (params) => ({ type: types.TODO_LIST, payload: { // 应用了 promiseMiddleware 中间件 promise: todoListSvr(params), },});
// todoList_reducer.jsimport types from "./todoList_types";import initialState from "./todoList_state";// 工具函数,用于简化 reducer 代码export const createReducer = (initialparams, reducerMap) => ( params = initialparams, action) => { const reducer = reducerMap[action.type]; return reducer ? reducer(params, action.payload ? action.payload : {}, action.params) : params;};export default createReducer(initialState, { [`${types.TODO_LIST}_PENDING`]: (state) => { return Object.assign({}, state, { todoListLoading: true }); }, [`${types.TODO_LIST}_ERROR`]: (state) => { return Object.assign({}, state, { todoListLoading: false }); }, [`${types.TODO_LIST}_SUCCESS`]: (state, data) => { return Object.assign({}, state, { todoList: data, todoListLoading: false }); },});
// todoList_state.jsexport default { todoListLoading: false, todoList: [],};
能够看到,每写一个页面(性能)都要在 4 个文件里来回跳转。所以首先,最容易想到的就是合并文件,把 action、reducer、type、state 都放在一个文件中解决。这样能够解决来回跳转的问题。
而后再察看一下代码,能够发现沉余的就是 reducer 代码。而这外面次要就是 loading 状态的解决。
参考了许多文章,最终优化代码如下:
// todo.js// 接口import { todoListSvr } from "services/card";// typesexport const types = { TODO_LIST: "TODO_LIST",};// actions办法export const actions = { todoList: (obj) => ({ type: types.TODO_LIST, payload: { // 应用了 promiseMiddleware 中间件 promise: todoListSvr(params), }, }),};// state数据const initialState = { todoList: [],};// reducerexport default createReducer(initialState, { [`${types.TODO_LIST}_SUCCESS`]: (state, data) => Object.assign({}, state, { todoList: data }),});
// loadingReducer.jsconst loadingReducer = (state = {}, action) => { const { type } = action; const matches = /(.*)_(PENDING|SUCCESS|ERROR)/.exec(type); if (!matches) return state; const [, requestName, requestState] = matches; return { ...state, [requestName]: requestState === "PENDING", };};// 页面内应用:const mapStateToProps = (state) => ({ isLoading: loadingSelector(['TODO_LIST'])(state) })export const loadingSelector = (actions) => (state) => actions.some((action) => state.loadingReducer[action]);export default loadingReducer;
页面内应用:
import { loadingSelector } from "store/modules/loadingReducer";const mapStateToProps = (state) => ({ isLoading: loadingSelector(["TODO_LIST"])(state),});export default connect(mapStateToProps)(Todo);