代码之家  ›  专栏  ›  技术社区  ›  Alx_Wil95

从api映射对象数组

  •  0
  • Alx_Wil95  · 技术社区  · 4 年前

    // 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>
    2 回复  |  直到 4 年前
        1
  •  1
  •   Ryan Le    4 年前

    您需要使用数组初始化状态,这样映射函数就不会出错,并更正映射方式:

    • 使用数组初始化状态:
    const [getBirds, setGetBirds] = useState([]);
    
    return (
      <div>
        {getBirds.map((bird) => (
          <img src={bird.image} alt={bird.image}></img>
        ))}
      </div>
    );
    
    • 另外,请使用length检查数组,因为[]或{}都等于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;
    

    Edit focused-hertz-ux7im

        2
  •  0
  •   Saigon Bitmaster    4 年前
    Your init state of birds and setBirds should be an array [] not an object {}, also you don't need:
    const birds = Object.entries(getBirds). fetch return array of birds already.
    
    <img src={birds.map(image)} alt={birds.map(image)}></img> is wrong, the array loop map should render an image for each bird.
    
    Below code will run for your need:
    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