Reactjs 使用HackerNews API将请求分页到API

Reactjs 使用HackerNews API将请求分页到API,reactjs,api,pagination,promise.all,Reactjs,Api,Pagination,Promise.all,***问题很简单,我只是写了很多具体的东西*** 我在网上找了几个小时,似乎找不到答案。大多数分页都是在您从API调用收到数据后进行的,或者对于使用自己的服务器构建的backend node.js 我的问题是,我有一个返回500个ID数组的API请求。然后是第二个多API调用,通过每个ID循环进行promise API调用。我使用的是承诺。所有的方法。 完成此请求需要2-3分钟 目前,我制作了一个快速过滤器来获得前十个结果,因此它将显示,我可以渲染数据以处理其他事情,如渲染组件和样式 我的问题是

***问题很简单,我只是写了很多具体的东西***

我在网上找了几个小时,似乎找不到答案。大多数分页都是在您从API调用收到数据后进行的,或者对于使用自己的服务器构建的backend node.js

我的问题是,我有一个返回500个ID数组的API请求。然后是第二个多API调用,通过每个ID循环进行promise API调用。我使用的是承诺。所有的方法。 完成此请求需要2-3分钟

目前,我制作了一个快速过滤器来获得前十个结果,因此它将显示,我可以渲染数据以处理其他事情,如渲染组件和样式

我的问题是,我希望能够在API调用仍在进行时对数据进行分页

基本上,Promise.all发送一个包含10个id(10个API调用)的数组,然后继续获取。但是在第一组10之后,我想开始接收要渲染的数据

现在,我只能用我的过滤方法得到10。或者等待2-3分钟,以便渲染所有500个

这是我的request.js文件(它是我的应用程序组件的一部分,为了清晰起见,我把它分开了)

从“axios”导入axios;
从“瓶颈”导入瓶颈
常数限制器=新瓶颈({
马克斯:1,
分钟:333
})
导出常量请求=(setResults、searchBarType、setLoading)=>{
const searchBar=type=>{
常量对象={
‘新’:‘新闻界’,
“过去”:“,
“注释”:“用户”,
“询问”:“询问者”,
‘show’:‘showstories’,
“工作”:“工作故事”,
“顶部”:顶部,
“最佳”:最佳故事,
“用户”:“用户”
}
返回obj[type]?obj[type]:obj['new'];
}
let type=searchBar(searchBarType)
常量getData=()=>{
常量选项=类型
常量API_URL=`https://hacker-news.firebaseio.com/v0/${options}.json?print=pretty`;
返回新承诺((解决、拒绝)=>{
返回解析(axios.get(API_URL))
})
}
常量getIdFromData=(数据ID)=>{
常量API_URL=`https://hacker-news.firebaseio.com/v0/item/${dataId}.json?print=pretty`;
返回新承诺((解决、拒绝)=>{
返回解析(axios.get(API_URL))
})
}
const runasync functions=async()=>{
设置加载(真)
const{data}=await getData()
设firstTen=data.filter((d,i)=>i<10);
我保证(
firstTen.map(异步(d)=>{
const{data}=wait limiter.schedule(()=>getIdFromData(d))
console.log(数据)
返回数据;
})
)
。然后((newresults)=>setResults((results)=>[…results,…newresults]))
设置加载(错误)
//设置条件:检查搜索栏类型是否已更改,然后首先清除结果数组
}  
runAsyncFunctions()
}
这是我的App.js文件

    import React, { useState, useEffect } from 'react';
    import './App.css';
    import { SearchBar } from './search-bar';
    import { Results } from './results';
    import { Request } from '../helper/request'
    import { Pagination } from './pagination';

    function App() {
      const [results, setResults] = useState([]);
      const [searchBarType, setsearchBarType] = useState('news');
      const [loading, setLoading] = useState(false);
      const [currentPage, setCurrentPage] = useState(1);
      const [resultsPerPage] = useState(3);
      

      // Select search bar button type 
      const handleClick = (e) => {
        const serachBarButtonId = e.target.id;
        console.log(serachBarButtonId)
        setsearchBarType(serachBarButtonId)
      }
      
      // API calls
      useEffect(() => {
        Request(setResults, searchBarType, setLoading)
      }, [searchBarType])

      // Get current results 
      const indexOfLastResult = currentPage * resultsPerPage;
      const indexOfFirstResult = indexOfLastResult - resultsPerPage;
      const currentResults = results.slice(indexOfFirstResult, indexOfLastResult);

      // Change page
      const paginate = (pageNumber) => setCurrentPage(pageNumber); 


      return (
        <div className="App">
          <SearchBar handleClick={handleClick} />
          <Results results={currentResults} loading={loading} />
          <Pagination resultsPerPage={resultsPerPage} totalResults={results.length} paginate={paginate} />
        </div>
      );
    }

    export default App;
import React,{useState,useffect}来自“React”;
导入“/App.css”;
从“./search bar”导入{search bar};
从“/Results”导入{Results};
从“../helper/Request”导入{Request}
从“./Pagination”导入{Pagination};
函数App(){
const[results,setResults]=useState([]);
const[searchBarType,setsearchBarType]=useState('news');
const[loading,setLoading]=useState(false);
const[currentPage,setCurrentPage]=useState(1);
const[resultsPerPage]=useState(3);
//选择搜索栏按钮类型
常量handleClick=(e)=>{
const serachBarButtonId=e.target.id;
console.log(serachBarButtonId)
setsearchBarType(serachBarButtonId)
}
//API调用
useffect(()=>{
请求(setResults、searchBarType、setLoading)
},[searchBarType])
//获取当前结果
const indexOfLastResult=currentPage*resultsPerPage;
const indexOfFirstResult=indexOfLastResult-resultsPerPage;
const currentResults=results.slice(indexOfFirstResult,indexOfLastResult);
//换页
常量分页=(页码)=>setCurrentPage(页码);
返回(
);
}
导出默认应用程序;

我希望它是通用的,足以遵循指南。请问我任何有助于澄清的问题。我花了8-10个小时搜索并试图解决这个问题…

你可以继续使用你的过滤器,但你必须做一些更改,对于组件分页的道具你必须设置500行,以便用户可以选择他想要的页面,因为如果设置10行,用户可以选择的页面是1,2,3,4,但我们不需要将所有页面都放在1到34页,因为我们有500个ID。第二点,我们需要以页面大小等于3的页面从服务器获取数据,我们需要传递到RequeststartIndexlastIndex请求

Request.js

import axios from 'axios';
    import BottleNeck from 'bottleneck'

    const limiter = new BottleNeck({
      maxConcurrent: 1, 
      minTime: 333
    })


    export const Request = (setResults, searchBarType, setLoading, startIndex, lastIndex) => {
      
      const searchBar = type => {
        const obj = {
          'new': 'newstories',
          'past': '',
          'comments': 'user',
          'ask': 'askstories',
          'show': 'showstories',
          'jobs': 'jobstories',
          'top': 'topstories',
          'best': 'beststories',
          'user': 'user'
        }
      
        return obj[type] ? obj[type] : obj['new'];
      }

      let type = searchBar(searchBarType)

      const getData = () => {
        const options = type
        const API_URL = `https://hacker-news.firebaseio.com/v0/${options}.json?print=pretty`;

        return new Promise((resolve, reject) => {
          return resolve(axios.get(API_URL))
        })
      }

      const getIdFromData = (dataId) => {
        const API_URL = `https://hacker-news.firebaseio.com/v0/item/${dataId}.json?print=pretty`;
        return new Promise((resolve, reject) => {
          return resolve(axios.get(API_URL))
        })
      }


      const runAsyncFunctions = async () => {
        setLoading(true)
        const {data} = await getData()
        let ids = data.slice(firstIndex, lastIndex+1) // we select our ids by index

        Promise.all(
          ids.map(async (d) => {
            const {data} = await limiter.schedule(() => getIdFromData(d))
            console.log(data)
            return data;
          })
          )
          .then((newresults) => setResults((results) => [...results, ...newresults]))
          setLoading(false)
        // make conditional: check if searchBar type has changed, then clear array of results first
      }  
      

      runAsyncFunctions()
    }
      
    
App.js

import React, { useState, useEffect } from 'react';
    import './App.css';
    import { SearchBar } from './search-bar';
    import { Results } from './results';
    import { Request } from '../helper/request'
    import { Pagination } from './pagination';

    function App() {
      const [results, setResults] = useState([]);
      const [searchBarType, setsearchBarType] = useState('news');
      const [loading, setLoading] = useState(false);
      const [currentPage, setCurrentPage] = useState(1);
      const [resultsPerPage] = useState(3);
      

      // Select search bar button type 
      const handleClick = (e) => {
        const serachBarButtonId = e.target.id;
        console.log(serachBarButtonId)
        setsearchBarType(serachBarButtonId)
      }
      
      // API calls
      useEffect(() => {
        Request(setResults, searchBarType, setLoading, 0, 2) //we fetch the first 3 articles
      }, [searchBarType])

     

      // Change page
      const paginate = (pageNumber) => {
           // Get current results 
          const indexOfLastResult = currentPage * resultsPerPage;
          const indexOfFirstPost = indexOfLastResult - resultsPerPage;
          Request(setResults, searchBarType, setLoading, indexOfFirstPost , indexOfLastResult) //we fetch the 3 articles of selected page
          setCurrentPage(pageNumber); 
      }


      return (
        <div className="App">
          <SearchBar handleClick={handleClick} />
          <Results results={results} loading={loading} />
          <Pagination resultsPerPage={resultsPerPage} totalResults={500} paginate={paginate} />
        </div>
      );
    }

    export default App;
import React,{useState,useffect}来自“React”;
导入“/App.css”;
从“./search bar”导入{search bar};
从“/Results”导入{Results};
从“../helper/Request”导入{Request}
从“./Pagination”导入{Pagination};
函数App(){
const[results,setResults]=useState([]);
const[searchBarType,setsearchBarType]=useState('news');
const[loading,setLoading]=useState(false);
const[currentPage,setCurrentPage]=useState(1);
const[resultsPerPage]=useState(3);
//选择搜索栏按钮类型
常量handleClick=(e)=>{
const serachBarButtonId=e.target.id;
console.log(serachBarButtonId)
import React, { useState, useEffect } from 'react';
    import './App.css';
    import { SearchBar } from './search-bar';
    import { Results } from './results';
    import { Request } from '../helper/request'
    import { Pagination } from './pagination';

    function App() {
      const [results, setResults] = useState([]);
      const [searchBarType, setsearchBarType] = useState('news');
      const [loading, setLoading] = useState(false);
      const [currentPage, setCurrentPage] = useState(1);
      const [resultsPerPage] = useState(3);
      

      // Select search bar button type 
      const handleClick = (e) => {
        const serachBarButtonId = e.target.id;
        console.log(serachBarButtonId)
        setsearchBarType(serachBarButtonId)
      }
      
      // API calls
      useEffect(() => {
        Request(setResults, searchBarType, setLoading, 0, 2) //we fetch the first 3 articles
      }, [searchBarType])

     

      // Change page
      const paginate = (pageNumber) => {
           // Get current results 
          const indexOfLastResult = currentPage * resultsPerPage;
          const indexOfFirstPost = indexOfLastResult - resultsPerPage;
          Request(setResults, searchBarType, setLoading, indexOfFirstPost , indexOfLastResult) //we fetch the 3 articles of selected page
          setCurrentPage(pageNumber); 
      }


      return (
        <div className="App">
          <SearchBar handleClick={handleClick} />
          <Results results={results} loading={loading} />
          <Pagination resultsPerPage={resultsPerPage} totalResults={500} paginate={paginate} />
        </div>
      );
    }

    export default App;