admin管理员组文章数量:1326332
I want to show some news in my React app using Redux.
The problem is that I want to show the news for individual dates and I want to paginate the news.
In my API I print
{
pagination: {
count: 1000,
size: 10,
page: 1,
pages: 100
},
news: [
..
]
}
I know how to make a simple pagination, but I don't know how the API should work if I want to be able to show news for different dates in my app.
Until now (without dates), I have just kept a state news
and pagination
in my Redux reducer, and then checked if the page number equals the total number of pages to determine whether it should try loading more news.
But now that I potentially have many different dates and I want to keep all the news in the Redux store, I don't know how to structure it.
I can keep my API as it is, since filtering with GET parameter ?date=15-09-2017
will just decrease the number of news in the API result.
But would it still be possible to just keep all the news in an array in a news
variable in my reducer or do I have to structure it to be something like
news: {
'15-09-2017': {
news: [...],
pagination: {}
},
...
}
in order to keep track of the pagination for every single date?
I want to show some news in my React app using Redux.
The problem is that I want to show the news for individual dates and I want to paginate the news.
In my API I print
{
pagination: {
count: 1000,
size: 10,
page: 1,
pages: 100
},
news: [
..
]
}
I know how to make a simple pagination, but I don't know how the API should work if I want to be able to show news for different dates in my app.
Until now (without dates), I have just kept a state news
and pagination
in my Redux reducer, and then checked if the page number equals the total number of pages to determine whether it should try loading more news.
But now that I potentially have many different dates and I want to keep all the news in the Redux store, I don't know how to structure it.
I can keep my API as it is, since filtering with GET parameter ?date=15-09-2017
will just decrease the number of news in the API result.
But would it still be possible to just keep all the news in an array in a news
variable in my reducer or do I have to structure it to be something like
news: {
'15-09-2017': {
news: [...],
pagination: {}
},
...
}
in order to keep track of the pagination for every single date?
Share Improve this question asked Sep 15, 2017 at 9:10 JamgreenJamgreen 11.1k32 gold badges122 silver badges231 bronze badges 2- Do you mean you also need separate page for each date? – vtambourine Commented Sep 23, 2017 at 18:09
- I need to be able to press "load more" and then append the news to the already-loaded news for every single date – Jamgreen Commented Sep 23, 2017 at 19:38
2 Answers
Reset to default 8 +150A think a structure where you store your your news by id and ids per date would be good and flexible structure:
{
"byId": {
"10": { /* News */ },
"14": { /* News */ },
/* ... */
},
"listsByDate": {
"2017-08-24": {
"total": 100,
"pageSize": 10,
"page": 2,
"items": [
10,
14,
/* ... */
]
}
}
}
You can implement simple selectors for this structure:
const getNewsById = (state, id) => state.byId[id];
const getListByDate = (state, date) => state.listByDate[date];
const getPageOfList = (state, data) => getListByDate(state, date).page
/* ... */
const getNewsByDate = (state, date) => {
return getListByDate(state, data).items.map((id) => {
return getNewsById(state, id);
});
}
I would remend to keep storing all news in a single place (news
in your reducer), and use selectors to pute derived data.
To achieve this, you will need to store the current date (I suppose it's a some kind of filter in your app) in Redux store, so it can be used in your selector.
So your reducer will look like:
{
news: [], // you can keep all the news here
date: '15-09-2017', // selected date
page: 1, // current page
pagination: {
'15-09-2017': { ... }, // pagination info by date.
// You will need this only if you use the classic pager (with page numbers in UI)
// it's not needed in case of infinite scroll
}
}
And selectors:
import { createSelector } from 'reselect';
// select all news
const newsSelector = () => (state) => state.get('news');
// select date
const dateSelector = () => (state) => state.get('date');
// select page
const pageSelector = () => (state) => state.get('page');
// select news by date
const newsByDateSelector = () => createSelector(
newsSelector(),
dateSelector(),
(news, date, page) => news.filter((newsItem) => newsItem.get('date') === date)
);
const pageSize = 10;
const newsByDatePagedSelector = () => createSelector(
newsByDateSelector(),
pageSelector(),
(news, page) => news.slice(pageSize * (page - 1), pageSize * page)
);
Then you can use newsByDatePagedSelector
selector to get the needed news in your container:
import React from 'react';
import { connect } from 'react-redux';
import { createStructuredSelector } from 'reselect';
export class NewsContainer extends React.PureComponent {
ponentDidMount() {
// news by selected date are not loaded yet
if (!this.props.news) {
this.loadNews();
}
}
ponentWillReceiveProps(nextProps) {
// user navigated to the next page
if (this.props.news && !nextProps.news) {
this.loadNews();
}
}
loadNews() {
// fetch next 10 news from server
}
render() {
return (
<div>
this.props.news.map((newsItem) => ...)
</div>
);
}
}
const mapStateToProps = createStructuredSelector({
news: newsByDatePagedSelector(),
});
export default connect(mapStateToProps)(NewsContainer);
When user reach the last news by some date, you can request next 10 news from your API as usual with filter ?date=15-09-2017
and put them to your store. Redux and reselect will bring them to NewsContainer
as newsByDate
prop.
本文标签: javascriptPaginate datespecific results from an API with React and ReduxStack Overflow
版权声明:本文标题:javascript - Paginate date-specific results from an API with React and Redux - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742200227a2431759.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论