开发者问题收集

无法在 React 中显示获取的 API 数据

2020-10-16
303

我是 React 的完全初学者,我正在从 https://www.boredapi.com/documentation#endpoints-price 获取数据。使用 http://www.boredapi.com/api/activity/ ,您将获得一个随机活动对象,格式为

{
    "activity": "Learn Express.js",
    "accessibility": 0.25,
    "type": "education",
    "participants": 1,
    "price": 0.1,
    "link": "https://expressjs.com/",
    "key": "3943506"
} 

我正尝试使用 React Hooks 获取其中 10 个对象,然后显示它们。但是,当我尝试获取并显示单个活动名称时,使用下面的代码时什么也没有发生。我使用钩子初始化一个数组,并且每次获取时都想附加一个新对象

useFetch.js 获取活动

import {useState , useEffect} from 'react';


export default function useFetch(){
  const [activities,setActivities] = useState([]);
  const getActivities = async () =>{
    for(let k=0;k<10;k++){
      let response = await fetch("http://www.boredapi.com/api/activity/");
      let result = await response.json();
      setActivities((oldstate)=>[...oldstate,result])
     }
  }
  useEffect(()=>{
    getActivities();
  }, [])

  return {activities};
}

AcitivityBar.js 显示活动

    import React from 'react';
import useFetch from './useFetch';


export default function ActivityBar(){
  const {activities} = useFetch();
  console.log(activities)
  return (
    <div className="activities-container">
        {
          (activities.map((a , index)=>{
            return <h1 key = {index}>hi</h1>
          }))
        }
    </div>
  );
}
3个回答

您可以使用 Promise.all 来并行等待多个请求:

这将同时显示结果,而不是一个接一个地显示。

import { useState, useEffect } from 'react'

export default function useFetch() {
  const [activities, setActivities] = useState([])

  const getActivities = async () => {
    let arr = []
    for (let k = 0; k < 10; k++) {
      arr[k] =  new Promise(async (resolve, reject) => {
        fetch('http://www.boredapi.com/api/activity/').then((response) => {
          resolve(response.json())
        })
      })
    }
    Promise.all(arr).then((results) => {
      setActivities(results)
    })
  }
  useEffect(() => {
    getActivities()
  }, [])

  return { activities, getActivities }
}
ecoplaneteer
2020-10-16

您可能应该将迭代更改为如下形式:

const getActivities = async () =>{
    for(let k=0;k<10;k++){
      let response = await fetch("http://www.boredapi.com/api/activity/");
      let result = await response.json();
      setActivities(prev => [...prev, result])
     }
  }

useState 还有一个函数输入,它返回实际值。您不应该依赖活动,因为当所有项目一次加载时,它始终是一个空数组

Kevin
2020-10-16

确保使用扩展运算符从响应中正确附加新活动,如下所示:

let response = await fetch("http://www.boredapi.com/api/activity/");
let activity = await response.json();
setActivities(prev => [...prev, activity]);

编辑: 主要问题在于范围, activities 在渲染过程中不会持久保留。您应该考虑使用上一个值。

Aadil Mehraj
2020-10-16