我的 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";
我正在构建一个 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";