В вашем редукторе вы захотите проиндексировать посты по идентификатору, а также сохранить отсортированные идентификаторы. Это позволит вам эффективно просматривать сообщения, а также вести их список в порядке их получения (от самого старого до самого нового). Вы можете получить их в обратном порядке, используя селектор.
switch (action.type) {
case 'POSTS_RECEIVED':
return {
...state,
orderedPostIDs: posts.map(p => p.id),
postsById: posts.reduce((acc, post) => {
acc[post.id] = post;
}, {});
}
}
При этом orderedPostIDs
- это массив идентификаторов сообщений, а postsById
- это объект, где ключи - это идентификаторы сообщений, а значения - это posts.
function getPostByID(state, postId) {
return state.posts.postsById[id];
}
// Should use reselect here because it's returning a new array with every call
// oldest to newest - post are received from API in this order
function getPostsSortedByDateAscending(state) {
return state.posts.orderedPostIDs.map(id => getPostByID(state, id));
}
// Should use reselect here because it's returning a new array with every call
// newest to oldest
function getPostsSortedByDateDescending(state) {
// copy to new array, because Array.reverse mutates the value
return [].concat(getPostsSortedByDateAscending(state)).reverse();
}
Другой подход, который упрощает ваше состояние, - хранить только postsById
, как Макс прокомментировал ниже . Чтобы получить отсортированные записи, вы будете использовать Object.values (), а затем сортировать их по мере необходимости.
// oldest to newest - need to use reselect here
function getPostsSortedByDateAscending(state) {
return _.sortBy(Object.values(state.posts.postsById), p => p.date)
}
// oldest to newest - need to use reselect here
function getPostsSortedByDateDescending(state) {
// copy to new array, because Array.reverse mutates the value
return [].concat(getPostsSortedByDateAscending(state)).reverse();
}