当我应用过滤器时,它仅在项目的第一页上起作用。当我加载更多项目时,过滤器消失了,必须再次单击“过滤器”,这显然不好。我只想单击一次过滤,它将返回所有符合条件的项目。
现在,我正在使用的API仅有200多个项目。我是否应该仅进行3个分页的API调用,以下载API中的所有项目并将它们加入主阵列,然后从该本地主阵列进行过滤?这样,它将在页面上显示每个过滤的项目。
但是,假设我有一个API,它的数据库更大,有数千个数据点,那么我不想将所有内容都加载到本地数组中。我想知道如何一次过滤所有分页的项目并仅显示过滤的项目。
这是我的代码:
import React, {Component} from 'react';
import axios from 'axios';
import BookList from './BookList';
import LoadingButton from './LoadingButton';
import FilterButton from './FilterButton';
const root_api = "...";
const books_per_page = 15;
class HomePage extends Component{
constructor(props){
super(props);
this.state ={
books:[],
pageNum: 1,
isLoading: false,
isDataFetched: false,
isListComplete: false,
error:''};
}
//get 15 items at a time
getBooks(){
const requestUrl = `${root_api}books?page=${
this.state.pageNum
}&per_page=${book_per_page}`;
this.setState({
isLoading: true
});
axios.get(requestUrl)
.then(res=>{
res.data.length > 0
? this.setState({
books: [...this.state.books, ...res.data],
isLoading: false,
isDataFetched: true,
pageNum: this.state.pageNum + 1
})
: this.setState({
isLoading: false,
isDataFetched: true,
isListComplete: true
});
})
.catch(err => {
console.log(err);
this.setState({
isLoading: false,
isDataFetched: false,
error: err.message
});
});
}
filterBooks(){
let newList =[];
let currentList = [];
currentList = this.state.books;
newList = currentList.filter(function(book){
return book.pages > 1200;
});
this.setState({books: newList});
}
render(){
return(
<div>
<FilterButton
isLoading={this.state.isLoading}
isListComplete={this.state.isListComplete}
clickHandler={()=>this.filterBooks()}
/>
{this.state.books.length > 0 &&(
<BookList books={this.state.books} />)}
<LoadingButton
isLoading={this.state.isLoading}
isListComplete={this.state.isListComplete}
clickHandler={()=>this.getBooks()}
/>
}
</div>
)
}}
答案 0 :(得分:1)
您无需创建主本地数组,只需创建另一个state
变量即可跟踪用户是否希望过滤图书:
constructor(props){
super(props);
this.state ={
books:[],
pageNum: 1,
isLoading: false,
isDataFetched: false,
isListComplete: false,
error:'',
filtered: false // this is the new variable
};
}
以及更改一些功能:
getBooks(){
const requestUrl = `${root_api}books?page=${
this.state.pageNum
}&per_page=${book_per_page}`;
this.setState({
isLoading: true
});
axios.get(requestUrl)
.then(res=>{
let newState = {
isDataFetched: true,
isLoading: false
}
if (res.data.length > 0) {
newState.pageNum = this.state.pageNum + 1
newState.books = [
...this.state.books,
...res.data
]
} else {
newState.isListComplete = true
}
this.setState(newState);
}).catch(err => {
console.log(err);
this.setState({
isLoading: false,
isDataFetched: false,
error: err.message
});
});
}
filterBooks(){
this.setState(prevState => ({
filtered: !prevState.filtered
}));
}
编辑:并更改渲染方法:
render() {
let bookListView
if (this.state.books.length > 0) {
let bookArr = this.state.books
if (this.state.filtered) {
bookArr = bookArr.filter(item => item.pages > 1200)
}
bookListView = <BookList books={bookArr} />
}
return(
<div>
<FilterButton
isLoading={this.state.isLoading}
isListComplete={this.state.isListComplete}
clickHandler={()=>this.filterBooks()}
/>
{bookListView}
<LoadingButton
isLoading={this.state.isLoading}
isListComplete={this.state.isListComplete}
clickHandler={()=>this.getBooks()}
/>
</div>
)
}
编辑:我将过滤部分移到了render
方法中,因此,如果您的用户想取消过滤其结果。