如何使用React调用多个页面调用API

发布于 2025-02-11 01:26:41 字数 2443 浏览 1 评论 0原文

我确实有一个API需要获取我的React应用程序。挑战是我有一个示例的API中不存在总页数。另外,每个API呼叫限制一次仅获得1000个记录。我确实有一个应该按页面上的按钮,但是我认为它不应该按照自己的作用,在获取了所有数据后,它仍然会进行API调用。我的问题是:

  1. 我如何获取API,因此即使有一个限制,所有5000个记录都将填充

  2. 我如何使按钮一次fetch api在一次不会消失的1000个记录中,因为该按钮是故障的,当我单击它,它将获取1000,但消失了。

      const perpage = 1000;
      const [page,setPage] = usestate([]);
      const [用户列表,setUserList] = usestate([]);
      const [加载,setloading] = usestate(false);
      const [load,setload] = usestate([]);
    
      useeffect(()=> {
        const getUserList =()=> {
          setloading(true);
          拿来(
            `/forms?page = $ {page}& count = $ {perpage}`,
            {标题}
          )
            然后。
            。然后((res)=> {
              //setTotalPages(Res.total_pages);
              setload(res.elements);
               setUserList(res.elements);
                setPage(res.page);
              if(res.elements.length === 0){
                console.log(“数组为空”);
                警报(“空”);
                setloading(false);
              }
    
              console.log(res);
            });
        };
        getUserList();
      }, [页]);
    
      返回 (
        < div className =“ app”>
    
          {userList.map(((x,i)=> {
            返回 (
              < div key = {i} className =“ box”>
                < div className =“ name”> {x.name + 1}</div>
              </div>
            );
          })}}
    
        < button className =“ btn-load-more” onclick = {()=> setPage(page + 1)}>
          {加载中 ? “加载...”:“加载更多”}
        </butt>
    
        </div>
      );
     
      {
        “元素”:[{{
        “ type”:“ landingpage”,
        “ CurrentStatus”:“草稿”,
        “ id”:“ 21”,
        “创建”:“ 1424811452”,
        “创建”:“ 5”,
        “深度”:“最小”,
        “ folderid”:“ 3655”,
        “名称”:“默认着陆页”,
        “权限”:[“检索”,“ setSecurity”,“ delete”,“ update”],,
        “更新”:“ 1424811452”,
        “更新”:“ 5”,
        “排除Fromauthentication”:“ false”,
        “ htmlcontent”:{
        “ type”:“ structuredhtmlcontent”,
        “ contentsource”:“编辑器”
        },,
        “相对路径”:“/default_lp”
        },{
        “ type”:“ landingpage”,
        “ CurrentStatus”:“草稿”,
        “ id”:“ 22”,
        “创建”:“ 1432583568”,
        “创建”:“ 9”,
        “深度”:“最小”,
        “ folderid”:“ 3655”,
        “名称”:“测试着陆页”,
        “权限”:[“检索”,“ setSecurity”,“ delete”,“ update”],,
        “ UpdatedAt”:“ 1432583653”,
        “更新”:“ 9”,
        “排除Fromauthentication”:“ false”,
        “ htmlcontent”:{
        “ type”:“ rawhtmlcontent”,
        “ contentsource”:“上传”
        },,
        “相对路径”:“/test_landing_page”
        }],
        “页面”:1,
        “ pageize”:1000,
        “总计”:5000
        } 
     

`

I do have an API that I need to fetch into my react app. The challenge is the number of total pages doesn't exist in the API where I have the example. Also, every API call limit only gets 1000 records at a time. I do have a button that is supposed to go page by page, but I don't think it's working as it should, after all the data is fetched, it would still make an API call. My question is :

  1. How do I fetch the API so all the 5000 records will populate even though there's a limit

  2. How do I make the button to fetch API to load 1000 records at a time that doesn't disappear, because the button is buggy, when I click on it, it'll fetch 1000, but it disappears.

    const perPage = 1000;
      const [page, setPage] = useState([]);
      const [userList, setUserList] = useState([]);
      const [loading, setLoading] = useState(false);
      const [load, setload] = useState([]);
    
      useEffect(() => {
        const getUserList = () => {
          setLoading(true);
          fetch(
            `/forms?page=${page}&count=${perPage}`,
            { headers }
          )
            .then((res) => res.json())
            .then((res) => {
              //setTotalPages(res.total_pages);
              setload(res.elements);
               setUserList(res.elements);
                setPage(res.page);
              if (res.elements.length === 0) {
                console.log("array is empty");
                alert("empty");
                setLoading(false);
              }
    
              console.log(res);
            });
        };
        getUserList();
      }, [page]);
    
      return (
        <div className="App">
    
          {userList.map((x, i) => {
            return (
              <div key={i} className="box">
                <div className="name">{x.name + 1} </div>
              </div>
            );
          })}
    
        <button className="btn-load-more" onClick={() => setPage(page + 1)}>
          {loading ? "Loading..." : "Load More"}
        </button>
    
        </div>
      );
    
        {
        "elements": [{
        "type": "LandingPage",
        "currentStatus": "Draft",
        "id": "21",
        "createdAt": "1424811452",
        "createdBy": "5",
        "depth": "minimal",
        "folderId": "3655",
        "name": "Default Landing Page",
        "permissions": ["Retrieve", "SetSecurity", "Delete", "Update"],
        "updatedAt": "1424811452",
        "updatedBy": "5",
        "excludeFromAuthentication": "false",
        "htmlContent": {
        "type": "StructuredHtmlContent",
        "contentSource": "editor"
        },
        "relativePath": "/Default_LP"
        }, {
        "type": "LandingPage",
        "currentStatus": "Draft",
        "id": "22",
        "createdAt": "1432583568",
        "createdBy": "9",
        "depth": "minimal",
        "folderId": "3655",
        "name": "Test Landing Page",
        "permissions": ["Retrieve", "SetSecurity", "Delete", "Update"],
        "updatedAt": "1432583653",
        "updatedBy": "9",
        "excludeFromAuthentication": "false",
        "htmlContent": {
        "type": "RawHtmlContent",
        "contentSource": "upload"
        },
        "relativePath": "/Test_Landing_Page"
        }],
        "page": 1,
        "pageSize": 1000,
        "total": 5000
        } 
    

`

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

墨离汐 2025-02-18 01:26:41

公平地说,如果您知道API将始终有5个总页面并且不会阻止多个请求,那么我会以下面的方式进行:


export default function SomeComponent(){

   useEffect(() => {
    

    (async () => {
       try {
          let promises = [];

          new Array(5).forEach(page => {
               let promise = new Promise(async (resolve, reject) => {
               try {
                   let response = await fetch('your url');
                   let json = await response.json();
                   if(response.status !== 200) reject("ERR: " + response.status)
                   resolve(json)
               }catch(err){
                   reject(err.message)
               }
            })
            promises.push(promise)
          })

         let results = await Promise.all(promises)
         //here you have all 5000 rows unless a request fails

       }catch(err){
         //handle the error
       }
     
    })()
        
   }, [])


   return (
      //your jsx here
   )
}

Update
我打开了一个沙盒并使用了Randomuser.me,它具有分页的端点,并使其与您的方法一起使用,因此您在setload()中添加的值可能会出现问题。我唯一要做的是为React 18 UseFect()double渲染添加一个abortController。在此示例中,我没有下一页号或总数

if(page === total/perPage){
 ...
}
import { useEffect, useState } from "react";
import "./styles.css";

export default function App() {
  let [page, setPage] = useState(1);
  const [users, setUsers] = useState([]);

  useEffect(() => {
    let abortController = new AbortController();
    let { signal } = abortController;
    fetch(`https://randomuser.me/api/?page=${page}&results=10`, {
      signal
    })
      .then((res) => res.json())
      .then((data) => {
        console.log(data);
        setUsers((prev) => [...prev, ...data.results]);
        if (page < 10) {
          console.log(page);
          setPage(page + 1);
        }
      })
      .catch((err) => {
        if (err.name === "AbortError") {
          setUsers([]);
        }
      });

    return () => {
      abortController.abort();
    };
  }, [page]);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

To be fair, if you know that the API will always have 5 total pages and it doesn't block multiple requests, I would do it in the following way:


export default function SomeComponent(){

   useEffect(() => {
    

    (async () => {
       try {
          let promises = [];

          new Array(5).forEach(page => {
               let promise = new Promise(async (resolve, reject) => {
               try {
                   let response = await fetch('your url');
                   let json = await response.json();
                   if(response.status !== 200) reject("ERR: " + response.status)
                   resolve(json)
               }catch(err){
                   reject(err.message)
               }
            })
            promises.push(promise)
          })

         let results = await Promise.all(promises)
         //here you have all 5000 rows unless a request fails

       }catch(err){
         //handle the error
       }
     
    })()
        
   }, [])


   return (
      //your jsx here
   )
}

UPDATE
I opened a sandbox and used randomuser.me which has paginated endpoints and made it work with your approach so there is probably something going wrong with the value you add in setload(). The only extra thing I did is to add an AbortController for React 18 useEffect() double render. In this example I don't have the next page number or the total but if you have them you can calculate the final request with something like

if(page === total/perPage){
 ...
}
import { useEffect, useState } from "react";
import "./styles.css";

export default function App() {
  let [page, setPage] = useState(1);
  const [users, setUsers] = useState([]);

  useEffect(() => {
    let abortController = new AbortController();
    let { signal } = abortController;
    fetch(`https://randomuser.me/api/?page=${page}&results=10`, {
      signal
    })
      .then((res) => res.json())
      .then((data) => {
        console.log(data);
        setUsers((prev) => [...prev, ...data.results]);
        if (page < 10) {
          console.log(page);
          setPage(page + 1);
        }
      })
      .catch((err) => {
        if (err.name === "AbortError") {
          setUsers([]);
        }
      });

    return () => {
      abortController.abort();
    };
  }, [page]);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文