在Redux状态下为对象中的每个项目更新单个值

时间:2019-08-06 09:32:26

标签: reactjs redux react-redux

我在redux状态下有一个通知列表。如下所示。

列表中可能会有更多项目,我的目标是根据isRead的值将列表中所有项目的true值设置为isDiscussionType。我在reducer中使用以下代码:

case MARKALLASREAD_NOTIFICATIONS_SUCCESS:
    return {
        ...state,
        loading: false,
        notifications:
            Object.keys(state.notifications).map(id => {
                if (state.notifications[id].isDiscussionType == action.payload.isDiscussionType)
                    return { ...state.notifications[id], isRead: true }
                else
                    return { ...state.notifications[id] }
            })

    };

此代码导致以下状态,其中key丢失(设置为0),并且isRead的值未更改(尽管数据库已正确更新)。

您在我上面共享的代码中看到任何问题吗?

enter image description here

2 个答案:

答案 0 :(得分:2)

Map返回数组而不是对象。这就是为什么丢失id的原因,因为0只是数组中的索引,该数组现在处于通知之下。我将通知的生成从返回中移出,以获得更大的灵活性:

case MARKALLASREAD_NOTIFICATIONS_SUCCESS:
    const notifications = { ...state.notifications }
    Object.values(notifications).forEach(notification => {
        if(notification.isDiscussionType === action.payload.isDiscussionType) {
           notifications[notification.id] { ...notification, isRead: true }
        }
    }
    return {
        ...state,
        loading: false,
        notifications
    };

如果isDiscussionType相同,则将返回一个不变的对象,其中每个通知均发生更改。因为map,filter,reduce return数组不存在,所以我将其移出return并使用forEach。

希望这会有所帮助。编码愉快。

答案 1 :(得分:0)

如果您的notifications是列表(即数组),则不应在其上使用Object.keys,而直接使用map

case MARKALLASREAD_NOTIFICATIONS_SUCCESS:
  return {
    ...state,
    loading: false,
    notifications: state.notifications.map(notification => {
      if (notification.isDiscussionType === action.payload.isDiscussionType) {
        return {
          ...notification,
          isRead: true
        }
      } else {
        return notification;
      }
    })
  };