【问题标题】:Reducer doesn't update state减速器不更新状态
【发布时间】:2021-07-18 20:06:00
【问题描述】:

我正在尝试创建一个 reducer 来更新对象中的属性,但我无法更新和存储新的状态信息

减速器

  export default function hideCardNumber(state = INITIAL_STATE, action: Action) { 
  if (action.type === 'HIDE_CARDNUMBER') {
  return { 
      ...state,
      data: {...state.data, action }}
  }
  else 
    return state
}

动作

export const toggleViewNumberCard = (cardId: number, hideCardNumber: boolean) => {
  return {
    type: 'HIDE_CARDNUMBER',
    cardId,
    hideCardNumber,
  }
}

派遣行动

 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, <-- Trying to replace this property when reducer update
    },
  ]
}

【问题讨论】:

    标签: reactjs react-native redux react-redux reducers


    【解决方案1】:

    你需要像这样更新reducer:

    const {hideCardNumber, cardId} = action;
    return { 
        ...state,
        data: state.data.map(item => item.cardId === cardId ? {...item, hideCardNumber} : item )
    }
    

    【讨论】:

    • 它仍然继续不创建新状态,我已经登录并且它返回第一个不可修改的状态
    • 你在dispatch动作的时候错了。请展示更多关于props.activeCard的信息以及您拨打handleToggleViewCardNumber的方式
    【解决方案2】:

    在实际场景中,cardID 将是一个哈希值。另外为了方便在应用增长时维护存储数据INITIAL_STATE应该是这样的。

     export const INITIAL_STATE = {
        activeCard: 0,
        data: {
            123456: {
                cardId: 123456,
                cardName: 'Card',
                cardUsername: 'Name',
                cardNumber: '1234 1234 1234 1234',
                hideCardNumber: false, 
          },
        }
      }
    

    那么Reducer会是这个样子。

    export default function hideCardNumber(state = INITIAL_STATE, action) {
        if (action.type === 'HIDE_CARDNUMBER') {
            return {
                ...state,
                data: {
                    ...state.data,
                    [action.cardId]: {
                        ...state.data[action.cardId],
                        hideCardNumber: action.hideCardNumber
                    }
                }
            }
        }
        else
            return state
    }
    

    如果 activeCardcards 中的 ID 之一匹配,则代码将完美运行。

    【讨论】:

      【解决方案3】:

      首先,最好将数据放入有效负载中,例如:

      export const toggleViewNumberCard = (cardId: number, hideCardNumber: boolean) => {
       return {
        type: 'HIDE_CARDNUMBER',
        payload : {
          cardId,
          hideCardNumber,
        }
      

      } }

      看起来你有很多卡片,首先你必须找到你想要使用 cardid 替换的当前卡片,如下所示:

        const index = state.data.findIndex(
          (card) => cardId === action.payload.cardId
        );
      

      然后复制你的旧数组:

            const newArray = [...state.data];
      

      然后用新的 hideCardNumber 值替换 newarray 的索引,如下所示:

        newArray[index] = {
          ...newArray[index],
          action.payload.hideCardNumber
        };
        return {
          ...state,
          data: newArray,
        };
      

      希望对你有帮助

      【讨论】:

        猜你喜欢
        • 2019-07-05
        • 2018-08-08
        • 1970-01-01
        • 2018-06-06
        • 2022-01-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多