Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在此处为每个页面仅发出一次API请求_Javascript_Reactjs - Fatal编程技术网

Javascript 如何在此处为每个页面仅发出一次API请求

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()

我正在开发一个React infinite scroll组件,它工作得非常好,唯一的一个小问题是,对于第1页,它发出两次API请求,这是我不想要的,对于其他页面,例如2、3、4,它只发出一次请求

我尝试了一切,但我无法修改代码,因此对于第1页,它只发出一次请求

我怎样才能只请求一次第1页呢? 这是工作代码

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()

非常感谢。我理解这个问题,并且解决方案对我有效。我接受了你的回答。很高兴这对我有帮助!