React中map函数内重复权限逻辑优化:自定义通用方法失效求助
问题:如何优化React中重复的权限更新代码?
我在React项目中有如下可正常运行的代码:
const newState = permissionData.map(obj => { if (obj.component.includes('Client')) { if ((permissionName.includes('Client')) && (name.includes('create'))) { return { ...obj, createPermission: event.target.checked ? 1 : 0 }; } if ((permissionName.includes('Client')) && (name.includes('view'))) { return { ...obj, viewPermission: event.target.checked ? 1 : 0 }; } if ((permissionName.includes('Client')) && (name.includes('delete'))) { return { ...obj, deletePermission: event.target.checked ? 1 : 0 }; } if ((permissionName.includes('Client')) && (name.includes('update'))) { return { ...obj, updatePermission: event.target.checked ? 1 : 0 }; } } if (obj.component.includes('Project')) { if ((permissionName.includes('Project')) && (name.includes('create'))) { return { ...obj, createPermission: event.target.checked ? 1 : 0 }; } if ((permissionName.includes('Project')) && (name.includes('view'))) { return { ...obj, viewPermission: event.target.checked ? 1 : 0 }; } if ((permissionName.includes('Project')) && (name.includes('delete'))) { return { ...obj, deletePermission: event.target.checked ? 1 : 0 }; } if ((permissionName.includes('Project')) && (name.includes('update'))) { return { ...obj, updatePermission: event.target.checked ? 1 : 0 }; } } if (obj.component.includes('Schema')) { if ((permissionName.includes('Schema')) && (name.includes('create'))) { return { ...obj, createPermission: event.target.checked ? 1 : 0 }; } if ((permissionName.includes('Schema')) && (name.includes('view'))) { return { ...obj, viewPermission: event.target.checked ? 1 : 0 }; } if ((permissionName.includes('Schema')) && (name.includes('delete'))) { return { ...obj, deletePermission: event.target.checked ? 1 : 0 }; } if ((permissionName.includes('Schema')) && (name.includes('update'))) { return { ...obj, updatePermission: event.target.checked ? 1 : 0 }; } } if (obj.component.includes('Dataset')) { if ((permissionName.includes('Dataset')) && (name.includes('create'))) { return { ...obj, createPermission: event.target.checked ? 1 : 0 }; } if ((permissionName.includes('Dataset')) && (name.includes('view'))) { return { ...obj, viewPermission: event.target.checked ? 1 : 0 }; } if ((permissionName.includes('Dataset')) && (name.includes('delete'))) { return { ...obj, deletePermission: event.target.checked ? 1 : 0 }; } if ((permissionName.includes('Dataset')) && (name.includes('update'))) { return { ...obj, updatePermission: event.target.checked ? 1 : 0 }; } } return obj; });
这段代码通过map遍历permissionData,根据不同组件类型和权限操作更新对应权限字段,但重复度较高。我尝试封装了如下通用方法来优化:
const checkPermission = (obj: object, type: string, permissionName: string, name: string, checked: boolean) => { if (obj.component.includes(type)) { if ((permissionName.includes(type)) && (name.includes('create'))) { return { ...obj, createPermission: checked }; } if ((permissionName.includes(type)) && (name.includes('view'))) { return { ...obj, viewPermission: checked }; } if ((permissionName.includes(type)) && (name.includes('delete'))) { return { ...obj, deletePermission: checked }; } if ((permissionName.includes(type)) && (name.includes('update'))) { return { ...obj, updatePermission: checked }; } } };
并通过checkPermission(obj, 'Client', permissionName, name, event.target.checked);调用,但方法未生效。请问该如何正确实现通用方法以优化这段重复代码?
解决方案
你的通用方法未生效主要有3个原因:
- 类型定义错误:
obj: object类型无法访问component属性,TypeScript会报错导致逻辑无法正常执行; - 未处理不匹配场景:当条件不满足时,
checkPermission没有返回原对象,会导致map结果中出现undefined; - 调用覆盖不全:仅调用了针对Client的检查,未处理Project、Schema、Dataset等其他类型。
以下是两种优化方案:
方案一:修复通用方法并批量调用
先修正类型定义,添加默认返回原对象的逻辑,再在map中遍历所有组件类型调用方法:
// 定义权限对象类型,避免TS报错 interface PermissionItem { component: string; createPermission?: number; viewPermission?: number; deletePermission?: number; updatePermission?: number; [key: string]: any; } const checkPermission = ( obj: PermissionItem, type: string, permissionName: string, name: string, checked: number ): PermissionItem => { if (obj.component.includes(type) && permissionName.includes(type)) { if (name.includes('create')) return { ...obj, createPermission: checked }; if (name.includes('view')) return { ...obj, viewPermission: checked }; if (name.includes('delete')) return { ...obj, deletePermission: checked }; if (name.includes('update')) return { ...obj, updatePermission: checked }; } // 不匹配则返回原对象 return obj; }; // 使用时遍历所有组件类型 const newState = permissionData.map(obj => { const checked = event.target.checked ? 1 : 0; let updatedObj = checkPermission(obj, 'Client', permissionName, name, checked); if (updatedObj === obj) updatedObj = checkPermission(obj, 'Project', permissionName, name, checked); if (updatedObj === obj) updatedObj = checkPermission(obj, 'Schema', permissionName, name, checked); if (updatedObj === obj) updatedObj = checkPermission(obj, 'Dataset', permissionName, name, checked); return updatedObj; });
方案二:简化逻辑,用组件类型数组遍历
把组件类型存入数组,循环查找匹配项,减少重复代码:
interface PermissionItem { component: string; createPermission?: number; viewPermission?: number; deletePermission?: number; updatePermission?: number; [key: string]: any; } const componentTypes = ['Client', 'Project', 'Schema', 'Dataset']; const newState = permissionData.map(obj => { const checked = event.target.checked ? 1 : 0; // 找到当前对象匹配的组件类型 const matchedType = componentTypes.find(type => obj.component.includes(type) && permissionName.includes(type)); if (!matchedType) return obj; // 根据操作类型更新对应字段 switch (true) { case name.includes('create'): return { ...obj, createPermission: checked }; case name.includes('view'): return { ...obj, viewPermission: checked }; case name.includes('delete'): return { ...obj, deletePermission: checked }; case name.includes('update'): return { ...obj, updatePermission: checked }; default: return obj; } });
这个方案去掉了额外的函数封装,直接在map中通过数组查找和switch逻辑处理,代码更简洁,也避免了多次函数调用的开销。
内容的提问来源于stack exchange,提问作者Nikhil
相关产品推荐
相关产品推荐

