如何将一个reducer中的数据添加到商店中的现有数据?

时间:2017-08-15 12:47:46

标签: reactjs redux react-redux

当用户在我的ReactJS应用中搜索时,他会得到结果。当用户滚动时,我想使用react-waypoint在无限滚动中加载下一组数据。 有效的是:

  • 加载初始项目集(并显示它们)
  • 触发航点滚动
  • 在滚动
  • 上递增页面计数器
  • 使用api中的项目将下一页加载到滚动
  • 中的nextItems

我无法工作的是将其添加到现有项目中。 我现在拥有的是一个单独的reducer,它将所有额外的数据加载到nextItems中。但我想简单地将其添加到现有项目中。我在items.js redurs中尝试了以下内容。但所有这一切都是为nextItems数组添加一个未定义的条目。不知怎的,我无法绕过这个。

export function items(state = [], action) {
    switch (action.type) {
        case 'ITEMS_FETCH_DATA_SUCCESS':
            return action.items;

        default:
            return state;
    }
}
export function nextItems(state = [], action) {
    switch (action.type) {
        case 'ITEMS_FETCH_NEXT_DATA_SUCCESS':
            return [...state.items, ...action.nextItems];

        default:
            return state;
    }
}

我觉得我必须将两个reducers组合在一起并将它们拆分为类型,或者在item.js动作文件中修复它。但我不知道如何让这个工作,我尝试的一切让我弄错了,或者根本没有。

我的行动:https://pastebin.com/zEPsxhb8

我的缩减者:https://pastebin.com/dSNFFff0

2 个答案:

答案 0 :(得分:1)

您应该可以使用Array.prototype.concat来实现此目的。

export function nextItems(state = [], action) {
    switch (action.type) {
        case 'ITEMS_FETCH_NEXT_DATA_SUCCESS':
            return Object.assign({}, 
                state.items, 
                state.items.concat(action.nextItems)
            );

        default:
            return state;
    }
}

答案 1 :(得分:1)

您可以使用我的功能。例如,您可以将此功能移动到Utils文件或其他服务。

{ ... // this is your reducer 
  return mergeObjectArrays(state, items, options.key || 'id');
}

mergeObjectArrays(arr1, arr2, key = 'id') {
  const res = arr1.slice();

  for (let item of arr2) {
    let index;
    if (typeof key === 'string') {
      index = arr1.findIndex((itm) => itm[key] == item[key]);
    }
    else {
      index = arr1.findIndex((itm) => {
        let eq = true;
        for (let i = 0; i < key.length; i++) {
          eq = eq && itm[key[i]] == item[key[i]]
        }
        return eq;
      });
    }

    if (index === -1) res.push(item);
    else res[index] = item;
  }

  return res;
}