来自 api 反应的对象数组映射

map array of objects from an api react

我一直试图通过映射从这个 API 获取图像以附加到页面,但我不断收到两条错误消息之一,说 'undefined.map is not a function' 或 'getBirds.map is not a function.'I've tried to leaving the array of objects as it is and setting state to an object and an array (at separate times) 但那没有用。我还尝试过使用 Object.key、Object.values 和 Object.entries(每个在不同的时间)将对象数组转换为数组,然后通过我的变量和 getBirds(再次分别),但这些尝试也失败了。我在下面附上了我的三个尝试。有人可以帮助我了解哪里出了问题吗?

// Attempt 1
import {useState, useEffect} from 'react'
import axios from 'axios'

function Birds(props) {
   const [getBirds, setGetBirds] = useState({})
   const {image} = props

   useEffect(() => {
      async function fetchBirds() {
         const URL = `https://audubon-society-api.herokuapp.com/birds`
         try {
            const res = await axios.get(URL)
            console.log(res.data)
            setGetBirds(res.data)
         } catch (error) {
            console.log(error)
         }
      }
      fetchBirds()
   }, [])
   
   if (!getBirds) return <h3>Loading...</h3>

   return (
      <div>
         <img src={getBirds.map(image)} alt={getBirds.map(image)}></img>
      </div>
   )
}

export default Birds

// Attempt 2
import {useState, useEffect} from 'react'
import axios from 'axios'

function Birds(props) {
   const [getBirds, setGetBirds] = useState([])
   const {image} = props

   useEffect(() => {
      async function fetchBirds() {
         const URL = `https://audubon-society-api.herokuapp.com/birds`
         try {
            const res = await axios.get(URL)
            console.log(res.data)
            setGetBirds(res.data)
         } catch (error) {
            console.log(error)
         }
      }
      fetchBirds()
   }, [])
   
   if (!getBirds) return <h3>Loading...</h3>

   return (
      <div>
         <img src={getBirds.map(image)} alt={getBirds.map(image)}></img>
      </div>
   )
}

export default Birds

// Attempt 3
import {useState, useEffect} from 'react'
import axios from 'axios'

function Birds(props) {
   const [getBirds, setGetBirds] = useState({})
   const {image} = props

   useEffect(() => {
      async function fetchBirds() {
         const URL = `https://audubon-society-api.herokuapp.com/birds`
         try {
            const res = await axios.get(URL)
            console.log(res.data)
            setGetBirds(res.data)
         } catch (error) {
            console.log(error)
         }
      }
      fetchBirds()
   }, [])

   const birds = Object.entries(getBirds)

   birds.forEach(([key, value]) => {
      console.log(key, value)
   })
   
   if (!getBirds) return <h3>Loading...</h3>

   return (
      <div>
         <img src={birds.map(image)} alt={birds.map(image)}></img>
      </div>
   )
}

export default Birds
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

你需要用一个数组来初始化你的状态,这样 map 函数就不会出错,并更正你映射它的方式:

  • 用数组初始化状态:
const [getBirds, setGetBirds] = useState([]);
  • 映射它:
return (
  <div>
    {getBirds.map((bird) => (
      <img src={bird.image} alt={bird.image}></img>
    ))}
  </div>
);
  • 此外,请检查您的数组的长度,因为 [] 或 {} 都等于 true。
if (!getBirds.length) return <h3>Loading...</h3>;

console.log(!![]);
console.log(!!{});

console.log(!![].length)

完成的解决方案:

import { useState, useEffect } from "react";
import axios from "axios";

function Birds(props) {
  const [getBirds, setGetBirds] = useState([]);

  useEffect(() => {
    async function fetchBirds() {
      const URL = 'https://audubon-society-api.herokuapp.com/birds';
      try {
        const res = await axios.get(URL);
        console.log(res.data);
        setGetBirds(res.data);
      } catch (error) {
        console.log(error);
      }
    }
    fetchBirds();
  }, []);

  if (!getBirds.length) return <h3>Loading...</h3>;

  return (
    <div>
      {getBirds.map((bird) => (
        <img src={bird.image} alt={bird.image}></img>
      ))}
    </div>
  );
}

export default Birds;

工作示例:

你的 birds 和 setBirds 的初始状态应该是一个数组 [] 而不是对象 {},你也不需要:

const birds = Object.entries(getBirds). 已经获取 return 个鸟类数组。

<img src={birds.map(image)} alt={birds.map(image)}></img>是错误的,数组循环映射应该为每只鸟渲染一个图像。

下面的代码将 运行 满足您的需要:

    import React, {useState, useEffect} from "react";
    import axios from 'axios';
    
    function Birds(props) {
      //- const [getBirds, setGetBirds] = useState([])
      //- const {image} = props
      // +
      const [birds, setGetBirds] = useState([])
      useEffect(() => {
         async function fetchBirds() {
            const URL = `https://audubon-society-api.herokuapp.com/birds`
            try {
               const res = await axios.get(URL)
               console.log(res.data)
               setGetBirds(res.data)
            } catch (error) {
               console.log(error)
            }
         }
         fetchBirds()
      }, [])
    
      // - const birds = Object.entries(getBirds)
    
      // - birds.forEach(([key, value]) => {
      // -   console.log(key, value)
      // - })
      
      // - if (!getBirds) return <h3>Loading...</h3>
      if (!birds) return <h3>Loading...</h3>
      return (
         <div>
          {/* <img src={birds.map(image)} alt={birds.map(image)}></img> */} 
           {birds.map((item, index) => 
            <img src={item.image} alt={index}></img>
            )}
         </div>
      )
    }
    
    export default Birds