我的 ReactJS 通量应用程序有太多的'actiontype'常量,如何将它们分开并命名为命名空间?



我正在构建一个涉及许多不同类型数据的通量应用以及资源的CRUD样式修改。这导致了大量的动作类型。他们中的大多数遵循相同的模式, REQUEST_ENTITY, REQUEST_ENTITY_SUCCESS, REQUEST_ENTITY_ERROR等。

如何将它们分成名称的常数?

理想情况下,而不是像:

那样访问它们
ActionTypes.REQUEST_ENTITY

我可以以更理智的方式访问它们,例如

ActionTypes.entity.REQUEST

为什么不跳过常数,而只使用字符串值?当然,您可能会不时误解一个,但是您可以很容易地将常数名称误认为,对吗?无论哪种方式,您的单位测试都会在同一位置失败,您会知道出了什么问题。

没有编译时间检查,这些常数列表的主要价值是代码有些自我记录,但是如果您在命名约定中保持一致,则可能不值得额外的努力将它们全部写成常数?

(我想那是一种非答案,但是我与他人进行了同样的对话,因此也可能值得在这里添加讨论。)

您可以简单地合并多个对象(也许从不同的文件导出)中ActionTypes

// entity_actions.js
module.exports = {
  entity: {
    REQUEST: "entity.REQUEST",
    DELETE: "entity.DELETE",
  }
};
// user_actions.js
module.exports = {
  user: {
    REQUEST: "user.REQUEST",
    DELETE: "user.DELETE",
  }
};
// actions.js
var entityActions = require("./entity_actions");
var userActions = require("./user_actions");
var ActionTypes = Object.assign({}, entityActions, userActions);

如果您的环境中没有Object.assign,则可以使用Underscore#extend或Object-Assign之类的东西。


我个人使用了一个小模块,我称为nestedKeyMirror,该模块采用一个大嵌套对象,并根据嵌套自动生成值:

function nestedKeyMirror(obj, namespace) {
  namespace = namespace || [];
  for (key in obj) {
    if (obj.hasOwnProperty(key) && obj[key] === null) {
      obj[key] = namespace.concat([key]).join(":");
    } else if (obj.hasOwnProperty(key) && typeof obj[key] === "object") {
      obj[key] = nestedKeyMirror(obj[key], namespace.concat([key]));
    }
  }
  return obj;
}

例如,在一个应用中,我定义了以下操作类型:

var actionTypes = nestedKeyMirror({
  LAYOUT: {
    RESIZE_PANE: null
  },
  CANVAS: {
    SET_PROPERTY: null
  },
  SHAPES: {
    ADD: null,
    SET_PROPERTY: null,
    SEND_BACKWARD: null,
    SEND_FORWARD: null,
    SEND_TO_BACK: null,
    SEND_TO_FRONT: null
  },
  SELECTION: {
    SELECT: null,
    DESELECT_ALL: null
  },
  HISTORY: {
    ADD: null,
    SELECT_INDEX: null
  }
});

这将给出,例如,actionTypes.SHAPES.ADD具有"SHAPES:ADD"的自动生成的字符串值。该技术可以与上面的对象合并策略结合在一起,以轻松创建深度嵌套的动作类型常数。

[更新:看起来有人最近发布了一个包装,该软件包在NPM上进行嵌套键镜像:Keymirror-nested]


如果问题是您的所有操作类型看起来都相似,则可以轻松地创建一个函数来生成它们(ES6计算的属性语法此处使用):

function generateActionType(type, base) {
  return {
    [base]: `${base}_${type}`,
    [`${base}_SUCCESS`]: `${base}_${type}_SUCCESS`,
    [`${base}_ERROR`]: `${base}_${type}_ERROR`
  };
}
ActionTypes.entity = {};
Object.assign(ActionTypes.entity, generateActionType("ENTITY", "REQUEST"));
Object.assign(ActionTypes.entity, generateActionType("ENTITY", "DELETE"));
ActionTypes.entity.REQUEST_SUCCESS === "REQUEST_ENTITY_SUCCESS";

最新更新