Javascript 如何在此处为每个页面仅发出一次API请求
我正在开发一个React infinite scroll组件,它工作得非常好,唯一的一个小问题是,对于第1页,它发出两次API请求,这是我不想要的,对于其他页面,例如2、3、4,它只发出一次请求 我尝试了一切,但我无法修改代码,因此对于第1页,它只发出一次请求 我怎样才能只请求一次第1页呢? 这是工作代码Javascript 如何在此处为每个页面仅发出一次API请求,javascript,reactjs,Javascript,Reactjs,我正在开发一个React infinite scroll组件,它工作得非常好,唯一的一个小问题是,对于第1页,它发出两次API请求,这是我不想要的,对于其他页面,例如2、3、4,它只发出一次请求 我尝试了一切,但我无法修改代码,因此对于第1页,它只发出一次请求 我怎样才能只请求一次第1页呢? 这是工作代码 import React, { useState, useEffect } from "react"; import axios from "axios"; function Lists()
import React, { useState, useEffect } from "react";
import axios from "axios";
function Lists() {
const [posts, setPosts] = useState([]);
const [newposts, setNewposts] = useState([]);
const [isFetching, setIsFetching] = useState(false);
const [page, setPage] = useState(1);
const LIMIT = 7;
const getPosts = () => {
axios.get(`https://jsonplaceholder.typicode.com/posts?_limit=${LIMIT}&_page=${page}`)
.then(res => {
setNewposts(res.data);
setPosts([...posts, ...res.data]);
setIsFetching(false);
})
};
const getMorePosts= () => {
setPage(page + 1);
getPosts();
}
const handleScroll = () => {
if (
window.innerHeight + document.documentElement.scrollTop !==
document.documentElement.offsetHeight
) return;
setIsFetching(true);
}
useEffect(() => {
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
useEffect(() => {
getPosts();
},[]);
useEffect(() => {
if (!isFetching){
return;
}
if( newposts.length > 0 ){
getMorePosts();
}
}, [isFetching]);
return (
<div className="App">
{posts.map((post, index) => (
<div key={index} className="post">
<div className="number">{post.id}</div>
<div className="post-info">
<h2 className="post-title">{post.title}</h2>
<p className="post-body">{post.body}</p>
</div>
</div>
))}
{isFetching && newposts.length > 0 && (
<div style = {{display: "flex", justifyContent:"center"}}>
<div className="spinner-border" role="status">
<span className="sr-only">Loading...</span>
</div>
</div>
)}
</div>
);
}
export default Lists;
import React,{useState,useffect}来自“React”;
从“axios”导入axios;
函数列表(){
const[posts,setPosts]=useState([]);
const[newposts,setNewposts]=useState([]);
const[isFetching,setIsFetching]=useState(false);
const[page,setPage]=useState(1);
常数极限=7;
const getPosts=()=>{
axios.get(`https://jsonplaceholder.typicode.com/posts?_limit=${LIMIT}&_page=${page}`)
。然后(res=>{
setNewposts(res.data);
setPosts([…posts,…res.data]);
setIsFetching(false);
})
};
const getMorePosts=()=>{
设置页面(第+1页);
getPosts();
}
常量handleScroll=()=>{
如果(
window.innerHeight+document.documentElement.scrollTop==
document.documentElement.offsetHeight
)返回;
setIsFetching(true);
}
useffect(()=>{
window.addEventListener(“滚动”,handleScroll);
return()=>window.removeEventListener(“滚动”,handleScroll);
}, []);
useffect(()=>{
getPosts();
},[]);
useffect(()=>{
如果(!正在获取){
返回;
}
如果(newposts.length>0){
getMorePosts();
}
},[isFetching]);
返回(
{posts.map((post,index)=>(
{post.id}
{post.title}
{post.body}
))}
{isFetching&&newposts.length>0&&(
加载。。。
)}
);
}
导出默认列表;
问题在于设置页面
与任何状态设置程序一样,都是异步工作的-它不会像您可能期望的那样立即更新页面
的值。页面的值
将仅在由状态更改触发的后续渲染中更新
这意味着在getMorePosts()
中,您并没有真正得到page+1
,您只是得到了page
这意味着在第一次渲染时,在另一次useffect
中调用getPosts()
,将page
设置为1
,然后在getMorePosts()调用中滚动并调用getPosts()
时再次调用它
后续调用只发生一次,因为在每次后续渲染中,getMorePosts()
递增page
至于修复方法,一个快速的方法可能是将page
作为getPosts
的参数,然后您可以在第一次渲染时静态调用getPosts(1)
,并保持其余逻辑相同,但将页面
状态初始化为2
,并将调用更改为getPage(page)
内部getMorePosts()
非常感谢。我理解这个问题,并且解决方案对我有效。我接受了你的回答。很高兴这对我有帮助!