使用函数创建对象时意外添加多余键的问题解决
问题描述
在Reducer中复用Dataformatter函数处理INIT_ACTIONS和ADD_ACTION两种场景时,INIT_ACTIONS运行正常,但ADD_ACTION会将新数据以addedAction为键包裹,而非直接添加格式化后的键值对。
相关代码:
const Dataformatter = (actionObject, data) => { return ({...actionObject, [`${data._id}-${data.positionId}`]: { status: data.tid.status, activatedDate: data.tid.activatedDate, stage: data.name, details: data.tid.details, submitted: data.submitted, taskHistory: data.tid.taskHistory, totalStepsInTask: data.totalStepsInTask, positionOfAction: data.positionOfAction, }}) } const actionReducer = (state, action) => { switch (action.type) { case "INIT_ACTIONS": console.log(action.actionData) let actionObject = {}; action.actionData.map((data) => { actionObject = Dataformatter(actionObject, data) }); return actionObject; case "ADD_ACTION": const addedAction = Dataformatter({}, action.actionData) return {...state, addedAction } } }
控制台输出的异常State:
6380259267885e98ca349938-6380259267885e98ca349936-1: {status: 'In Progress', activatedDate: '2022-11-25T02:16:50.588Z', stage: 'Design', details: {…}, submitted: false, …} addedAction: {63812949d5cf2ce2cf32284a-63812949d5cf2ce2cf32...}
解决方案
问题出在ADD_ACTION的返回语句中,{...state, addedAction }是ES6对象简写语法,等价于{...state, addedAction: addedAction},会把格式化后的对象作为addedAction键的值,而非直接合并其内部的键值对。
只需修改为展开addedAction对象,即可将新生成的键直接合并到state中:
case "ADD_ACTION": const addedAction = Dataformatter({}, action.actionData) return {...state, ...addedAction }
另外,INIT_ACTIONS里用map遍历赋值的写法不够合理(map的核心作用是生成新数组),可以用Array.reduce简化代码,更贴合函数式编程风格:
case "INIT_ACTIONS": console.log(action.actionData) return action.actionData.reduce((acc, data) => Dataformatter(acc, data), {})
修改后,初始化和新增操作都会正确生成以${data._id}-${data.positionId}为键的对象结构,不会出现多余的包裹键。
内容的提问来源于stack exchange,提问作者Michael Ratcliffe
相关产品推荐
相关产品推荐

