Reactjs Redux:具有多个不同 GET 请求的无限滚动
Reactjs Redux: Infinite scroll with multiple different GET requests
我在 reactjs 中构建了一个无限滚动,其中数据从与用户点击页面底部相同的 API 加载。现在,这里的问题是从多个不同的 API 获取数据以获取其他 data.So,实现 this.Please 的正确方法是什么 this.Here 是我的代码。
import React from "react";
import { Link } from 'react-router-dom';
import axios from 'axios';
const BUSY = {};
class InfiniteData extends React.Component{
constructor(props){
super(props);
this.state={
olddata: [],
newData: [],
requestSent: false,
scrollCounter:1
}
this.handleOnScroll = this.handleOnScroll.bind(this)
this.buildData = this.buildData.bind(this)
}
componentDidMount(){
window.addEventListener('scroll', this.handleOnScroll);
this.doQuery(1).then(res=>
this.setState({
newData: this.state.newData.slice().concat(res),
requestSent: false
}))
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleOnScroll);
}
queryActive = false;
doQuery(queryParam) {
if(this.queryActive){
return Promise.resolve(BUSY);
}
this.queryActive=true;
switch(queryParam){
case 1: return this.buildData(queryParam).then((res)=>res).catch(err=>{})
break;
case 2: return this.buildData(queryParam).then((res)=>res);
break;
case 3: return this.buildData(queryParam).then((res)=>res);
break;
case 4: return this.buildData(queryParam).then((res)=>res);
break;
default: return true;
}
}
buildData(queryParam){
//there is no paging in getting posts, won't it just get the same posts?
return axios.get("https://jsonplaceholder.typicode.com/posts")
.then( res=> {this.queryActive=false;return res.data;})
.catch(err=>{
this.queryActive=false;
return Promise.reject(err);
})
}
handleOnScroll(){
var scrollCounter=0;
var scrollTop = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
var scrollHeight = (document.documentElement && document.documentElement.scrollHeight) || document.body.scrollHeight;
var clientHeight = document.documentElement.clientHeight || window.innerHeight;
var scrolledToBottom = Math.ceil(scrollTop + clientHeight) >= scrollHeight;
if (scrolledToBottom) {
this.setState({
scrollCounter: this.state.scrollCounter + Math.floor(scrolledToBottom)
})
if(this.state.scrollCounter<5){
this.doQuery(this.state.scrollCounter).then(res=>
(res===BUSY)
? false
: this.setState({
newData: this.state.newData.slice().concat(res)
})
)
.catch(err=>this.setState({requestSent: false}))
this.setState({requestSent: true});
}else{
return true
}
}
}
render()
{
return (
<div>
<div className="data-container">
<div className="row ">
{this.state.newData && this.state.newData.map((dat,i)=>
<div key={i} className="col-lg-4">
<div className="bordered">
{dat.body}
</div>
</div>
)}
</div>
</div>
</div>
);
}
}
export default InfiniteData;
您可以添加一个名为 BUSY 的常量,供 doQuery 用作 return 值,用于表示它已经忙于发出请求:
import React from "react";
import { Link } from 'react-router-dom';
import axios from 'axios';
const BUSY = {};
您可以对 doQuery 进行一些更改:
queryActive = false;
doQuery() {
if(this.queryActive){
return Promise.resolve(BUSY);
}
this.queryActive=true;
//there is no paging in getting posts, won't it just get the same posts?
return axios.get("https://jsonplaceholder.typicode.com/posts")
.then( res=> {this.queryActive=false;return res.data;})
.catch(err=>{
//before you were only console.logging the error but that causes you
// to create a promise that doesn't reject but resolves with undefined
// when something goes wrong
this.queryActive=false;
console.warn(err);
return Promise.reject(err);
})
}
当您调用 doQuery 时,请确保您忽略了结果,如果结果是 BUSY:
this.doQuery().then(res=>
(res===BUSY)
? false
: this.setState({
newData: this.state.newData.slice().concat(res)
})
)
.catch(err=>this.setState({requestSent: false}))
this.setState({requestSent: true});
我在 reactjs 中构建了一个无限滚动,其中数据从与用户点击页面底部相同的 API 加载。现在,这里的问题是从多个不同的 API 获取数据以获取其他 data.So,实现 this.Please 的正确方法是什么 this.Here 是我的代码。
import React from "react";
import { Link } from 'react-router-dom';
import axios from 'axios';
const BUSY = {};
class InfiniteData extends React.Component{
constructor(props){
super(props);
this.state={
olddata: [],
newData: [],
requestSent: false,
scrollCounter:1
}
this.handleOnScroll = this.handleOnScroll.bind(this)
this.buildData = this.buildData.bind(this)
}
componentDidMount(){
window.addEventListener('scroll', this.handleOnScroll);
this.doQuery(1).then(res=>
this.setState({
newData: this.state.newData.slice().concat(res),
requestSent: false
}))
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleOnScroll);
}
queryActive = false;
doQuery(queryParam) {
if(this.queryActive){
return Promise.resolve(BUSY);
}
this.queryActive=true;
switch(queryParam){
case 1: return this.buildData(queryParam).then((res)=>res).catch(err=>{})
break;
case 2: return this.buildData(queryParam).then((res)=>res);
break;
case 3: return this.buildData(queryParam).then((res)=>res);
break;
case 4: return this.buildData(queryParam).then((res)=>res);
break;
default: return true;
}
}
buildData(queryParam){
//there is no paging in getting posts, won't it just get the same posts?
return axios.get("https://jsonplaceholder.typicode.com/posts")
.then( res=> {this.queryActive=false;return res.data;})
.catch(err=>{
this.queryActive=false;
return Promise.reject(err);
})
}
handleOnScroll(){
var scrollCounter=0;
var scrollTop = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
var scrollHeight = (document.documentElement && document.documentElement.scrollHeight) || document.body.scrollHeight;
var clientHeight = document.documentElement.clientHeight || window.innerHeight;
var scrolledToBottom = Math.ceil(scrollTop + clientHeight) >= scrollHeight;
if (scrolledToBottom) {
this.setState({
scrollCounter: this.state.scrollCounter + Math.floor(scrolledToBottom)
})
if(this.state.scrollCounter<5){
this.doQuery(this.state.scrollCounter).then(res=>
(res===BUSY)
? false
: this.setState({
newData: this.state.newData.slice().concat(res)
})
)
.catch(err=>this.setState({requestSent: false}))
this.setState({requestSent: true});
}else{
return true
}
}
}
render()
{
return (
<div>
<div className="data-container">
<div className="row ">
{this.state.newData && this.state.newData.map((dat,i)=>
<div key={i} className="col-lg-4">
<div className="bordered">
{dat.body}
</div>
</div>
)}
</div>
</div>
</div>
);
}
}
export default InfiniteData;
您可以添加一个名为 BUSY 的常量,供 doQuery 用作 return 值,用于表示它已经忙于发出请求:
import React from "react";
import { Link } from 'react-router-dom';
import axios from 'axios';
const BUSY = {};
您可以对 doQuery 进行一些更改:
queryActive = false;
doQuery() {
if(this.queryActive){
return Promise.resolve(BUSY);
}
this.queryActive=true;
//there is no paging in getting posts, won't it just get the same posts?
return axios.get("https://jsonplaceholder.typicode.com/posts")
.then( res=> {this.queryActive=false;return res.data;})
.catch(err=>{
//before you were only console.logging the error but that causes you
// to create a promise that doesn't reject but resolves with undefined
// when something goes wrong
this.queryActive=false;
console.warn(err);
return Promise.reject(err);
})
}
当您调用 doQuery 时,请确保您忽略了结果,如果结果是 BUSY:
this.doQuery().then(res=>
(res===BUSY)
? false
: this.setState({
newData: this.state.newData.slice().concat(res)
})
)
.catch(err=>this.setState({requestSent: false}))
this.setState({requestSent: true});