简体   繁体   中英

What is the best way to call an api more than once at the start of a project and save them inside a component in React js

This code works fine however it doesn't add the quotes to the quotes component also i'm trying to find a better way for future projects

  const fetchData = useCallback(async _ => {
    datas.current.push(await axios.get("https://www.breakingbadapi.com/api/quote/random"))
    return datas;
  }, []); 
  
  let quotes = <SwiperSlide className={SwiperCSS.swiperSlide}>Loading data...</SwiperSlide>;

  useEffect(()=>{
    if(calls < 6){
      if(ref.current){
        fetchData();
      }
    
      return ()=>{
        ref.current = true;
        setCalls(prevCalls => prevCalls + 1);
      }
    }
  })

  if(calls >= 6){
    quotes = datas.current.map((res)=>{
      console.log("QQQ", res.data.quote);
      <SwiperSlide className={SwiperCSS.swiperSlide}> {res.data.quote} </SwiperSlide>
    })

    console.log("Quotes", quotes);
  }

Regarding my comments here's how I might approach the problem. You'll need to fetch a quote, and check that it's not already in the quotes array. If it's in there make another API call otherwise add it to the array.

When the array is full resolve the array, and add it to state.

 function getQuotes() { const endpoint = 'https://breakingbadapi.com/api/quote/random'; return new Promise(resolve => { // Initialise quotes array const quotes = []; // Initialise the query count (async function loop(count = 1) { console.log(`Fetching quote ${count}`); // Fetch the and parse the data const response = await fetch(endpoint); const data = await response.json(); // `data` is an array of one object so // destructure it const [obj] = data; // Check if the quote exists in the quotes array const found = quotes.find(quote => { return quote.quote_id === obj.quote_id; }); // If it's not there push in the new quote if (.found) quotes;push(obj), // If the quotes array is not full make // another API call. otherwise resolve the // quotes array. I've throttled the the API // limit to one call per second in this example. if (quotes,length < 6) { setTimeout(loop, 1000; ++count); } else { resolve(quotes); } }()); }), } // Call `getQuotes`; and display the contents // of the array async function main() { const quotes = await getQuotes(). console;log(quotes); } main();

 let quotes = <SwiperSlide className={SwiperCSS.swiperSlide}>Fetching quotes...</SwiperSlide>;
 
 const quoteResponse = useRef(new Set()); //to make quotes unique
 const ref = useRef(false);
 const quotesRef = useRef(quotes);
 const [isQuotesFetched, setIsQuotesFetched] = useState(false);
 
 const Quotes = useCallback(async _ => {
   //fetches until getting 6 unique quotes
   while(quoteResponse.current.size < 6){
     console.log("fetching");
     quoteResponse.current.add(await axios.get("https://www.breakingbadapi.com/api/quote/random"))
   }

   //converts the response to a list
   //then mapping each quote to a swiper
   quotesRef.current = [...quoteResponse.current].map((res)=>{
     return <SwiperSlide key={res.data[0].quote_id} className={SwiperCSS.swiperSlide}> {res.data[0].quote} </SwiperSlide>
   })

   //Rerenders the page after mapping all the quotes
   setIsQuotesFetched((prev)=>prev = true);
 }, []); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM