Reputation: 770
When a user searches in my ReactJS app he gets results. When the user scrolls I want to load in the next set of data in an infinite scroll using react-waypoint. What works is the following:
What I can't get working is appending this to the existing items. What I have now is a seperate reducer which loads all the extra data into nextItems. But I want to simply add this to the existing items. I've tried the following in my items.js reducers. But all this does is add an undefined entry to the nextItems array. Somehow I can't wrap my head around this.
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;
}
}
I have the feeling that I have to combine both reducers and split them on type, or fix this in the item.js actions file. But I don't know how to get this working, and everything I tried got me either confusing errors, or nothing at all.
My actions: https://pastebin.com/zEPsxhb8
My reducers: https://pastebin.com/dSNFFff0
Upvotes: 0
Views: 1064
Reputation: 681
You can use my function. For example you can move this function to Utils file or other service.
{ ... // 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;
}
Upvotes: 1
Reputation: 2327
You should be able to acheive this with 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;
}
}
Upvotes: 1