Search code examples
reactjsaxiosreact-hooksuse-effectreact-functional-component

How do I properly set up an API call using useEffect?


Here is my entire component. In the console the correct data is showing up at "data" but when I try to run map on it it says "map is not a function." The 16 items in the console are the correct beaches.

import React, {useState, useEffect} from 'react';
import axios from 'axios';


export default function Beaches() {
    const [data, setData] = useState({beaches: []})
    // const [hasError, setErrors] = useState(false)


    useEffect(() => {
        const fetchBeaches = async () => {
            const result = await axios('http://localhost:3000/beaches');
            setData(result.data);}
            fetchBeaches();
        }, [])
            
    console.log(data)


return (

    <ul>
        {data.beaches.map(beach => (
            <button>{beach.name}</button>
        ))}
    </ul>
)
}

enter image description here


Solution

  • Because you're not setting the beaches data in state correctly.

    Replace useEffect code with this:

    useEffect(() => {
      const fetchBeaches = async () => {
        const result = await axios('http://localhost:3000/beaches');
        setData({beaches: result.data});
      }
      fetchBeaches();
    }, [])
    

    furthermore, you can improve the state structure of beaches data:

    import React, { useState, useEffect } from "react";
    import axios from "axios";
    
    export default function Beaches() {
      const [beaches, setBeaches] = useState([]);
      // const [hasError, setErrors] = useState(false)
    
      useEffect(() => {
        const fetchBeaches = async () => {
          const result = await axios("http://localhost:3000/beaches");
          setBeaches(result.data);
        };
        fetchBeaches();
      }, []);
    
    
      return (
        <ul>
          {beaches.map((beach) => (
            <button>{beach.name}</button>
          ))}
        </ul>
      );
    }