【问题标题】:map array of objects from an api react来自 api 的映射对象数组反应
【发布时间】:2021-11-09 06:31:06
【问题描述】:

我一直在尝试通过映射从此 API 获取图像以附加到页面,但我不断收到两条错误消息之一,说“undefined.map 不是函数”或“getBirds.map 不是一个函数。'我尝试将对象数组保持原样并将状态设置为一个对象和一个数组(在不同的时间),但这不起作用。我也尝试过使用 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>

【问题讨论】:

    标签: reactjs api async-await react-state array.prototype.map


    【解决方案1】:

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

    const birds = Object.entries(getBirds). fetch 已经返回鸟类数组。

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

    以下代码将根据您的需要运行:

        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
    

    【讨论】:

      【解决方案2】:

      你需要用一个数组来初始化你的状态,所以 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;
      

      工作示例:

      【讨论】:

      • 成功了,谢谢!我在第二次尝试中确实将它设置为一个数组,但是在我的 img src 和 alt 属性中进行了映射。为什么它是一个箭头函数,而不是我是怎么做的?
      • JS Array.map 返回一个数组,但 src 和 alt 分别接收单个字符串或 URL 和名称。您需要将其映射到标签之外并在数组中提供 src, alt 实际字符串。
      猜你喜欢
      • 2019-06-12
      • 2020-07-29
      • 2020-10-31
      • 2019-01-07
      • 2021-06-17
      • 1970-01-01
      • 2021-01-15
      • 2018-05-21
      • 1970-01-01
      相关资源
      最近更新 更多