关于react.js:Redux-瘦身之路

51次阅读

共计 2536 个字符,预计需要花费 7 分钟才能阅读完成。

前言

公司中台我的项目应用 redux 进行状态治理,家喻户晓,redux 写起来就是在节约生命。但鉴于我的项目重构老本太大,因而决定先在不扭转框架的状况下,在原先代码的根底上一步步优化简化 redux 用法。

优化

先来看看原来的文件目录构造:

├── store
│   └── modules
│       ├── todoList
│       │   ├── todoList_action.js
│       │   ├── todoList_reducer.js
│       │   ├── todoList_state.js
│       │   └── todoList_types.js

页面代码:

// todoList_types.js
export const types = {TODO_LIST: "TODO_LIST",};
// todoList_action.js
import 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.js
import 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.js
export default {
  todoListLoading: false,
  todoList: [],};

能够看到,每写一个页面(性能)都要在 4 个文件里来回跳转。所以首先,最容易想到的就是合并文件,把 action、reducer、type、state 都放在一个文件中解决。这样能够解决来回跳转的问题。

而后再察看一下代码,能够发现沉余的就是 reducer 代码。而这外面次要就是 loading 状态的解决。
参考了许多文章,最终优化代码如下:

// todo.js
// 接口
import {todoListSvr} from "services/card";
// types
export 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: [],
};
// reducer
export default createReducer(initialState, {[`${types.TODO_LIST}_SUCCESS`]: (state, data) =>
    Object.assign({}, state, { todoList: data}),
});
// loadingReducer.js
const 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);

正文完
 0