为什么Redux中的Reducer无法更新state内卡片的hideCardNumber属性?
问题描述
尝试编写Reducer来更新状态对象中的指定属性,但目前无法完成状态更新,也无法存储新的状态数据。
原有实现代码
原Reducer逻辑
export default function hideCardNumber(state = INITIAL_STATE, action: Action) { if (action.type === 'HIDE_CARDNUMBER') { return { ...state, data: {...state.data, action } } } else { return state } }
原Action定义
export const toggleViewNumberCard = (cardId: number, hideCardNumber: boolean) => { return { type: 'HIDE_CARDNUMBER', cardId, hideCardNumber, } }
原Action分发逻辑
function handleToggleViewCardNumber() { cards.map((card: Card) => { if (card.cardId === props.activeCard ) { dispatch(toggleViewNumberCard( card.cardId, !card.hideCardNumber, )) } }) }
原初始状态定义
export const INITIAL_STATE = { activeCard: 0, data: [ { cardId: 0, cardName: 'Card', cardUsername: 'Name', cardNumber: '1234 1234 1234 1234', hideCardNumber: false, // 尝试在Reducer更新时修改该属性 }, ] }
核心问题原因
- 状态结构适配错误:初始状态里的
data是数组类型,原Reducer误将其按对象结构展开,写出{...state.data, action}的错误代码。这种写法会把原本的数组转换成以数组索引为key的普通对象,还会把整个action的属性直接合并进去,彻底破坏原有数据结构,根本无法匹配预期的存储格式。 - 缺失目标定位逻辑:原Reducer没有根据action携带的
cardId参数,定位到数组中对应的单张卡片,自然没法精准修改hideCardNumber属性。
修正方案
修正后的Reducer实现
针对数组结构做遍历匹配,保证不可变更新的同时精准修改目标卡片属性:
export default function hideCardNumber(state = INITIAL_STATE, action: Action) { if (action.type === 'HIDE_CARDNUMBER') { return { ...state, data: state.data.map(card => { // 匹配和action携带的cardId一致的目标卡片 if (card.cardId === action.cardId) { // 返回全新的卡片对象,仅更新hideCardNumber属性,其余属性保持不变 return { ...card, hideCardNumber: action.hideCardNumber } } // 非目标卡片直接返回原对象,保持引用稳定 return card }) } } else { return state } }
优化后的分发逻辑
原逻辑用map遍历全量卡片来匹配目标,会触发不必要的循环和多余动作,可直接通过find定位激活卡片后分发动作:
function handleToggleViewCardNumber() { const targetCard = cards.find(card => card.cardId === props.activeCard) // 找不到目标卡片时直接返回,避免异常dispatch if (!targetCard) return dispatch(toggleViewNumberCard( targetCard.cardId, !targetCard.hideCardNumber, )) }
内容的提问来源于stack exchange,提问作者PORMAZION
相关产品推荐
相关产品推荐

