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

My ReactJS flux App has too many 'actiontype' constants, how can I separate and namespace them?

我正在构建一个 flux 应用程序,它涉及许多不同类型的数据,以及资源的 CRUD 样式修改。这导致大量的 ActionType。他们中的大多数都遵循相同的模式,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 or 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";