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

时间:2020-10-16 14:32:17

标签: reactjs api react-hooks

我是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钩子获取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 个答案:

答案 0 :(得分:1)

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

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

编辑: 主要问题是范围界定,activities在整个渲染过程中不会持久存在。您应该考虑使用prev值。

答案 1 :(得分:1)

您可能应该将迭代更改为以下内容:

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还具有一个返回实际值的函数输入。您不应该依赖活动,因为当所有项目一次加载时,该活动始终是一个空数组

答案 2 :(得分:1)

您可以使用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 }
}