You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.23 19:54:03