Search code examples
reactjsreact-hooksfetch

Unable to map over result of async fetch request in React Hook


I've found quite a few issues related to this but I don't seem to be able to find a solution that works and I'm not sure why.

I have a async fetch request in a react functional component. It returns some dummy JSON data, which I then want to map over.

Everything is returned correctly in the console.log (and in Postman), however when it comes to mapping the result I get

TypeError: Cannot read property 'map' of undefined

import "./App.css";
import React, { useState, useEffect } from "react";

function App() {
  const [dummyData, setDummyData] = useState([]);

  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/todos/1")
      .then((res) => {
        return res.json();
      })
      .then((data) => {
        setDummyData(data);
      });
  }, []);

  return (
    <div className="App">
      {console.log(dummyData)}

      {dummyData.map((d) => {
        return <h1> {d}</h1>;
      })}
    </div>
  );
}

export default App;

Can anyone help me understand why? I feel there may be some fundamental gaps in my knowledge on this?? Or am I missing something simple?

Adding a codesandbox to demo and initialising the state of dummyData

https://codesandbox.io/s/objective-benz-t1zpi?file=/src/App.js


Solution

  • https://jsonplaceholder.typicode.com/todos/1 returns an Object, Not an Array. dummyData is replaced with Object(once you receive response) which does not have array methods. That's why you're getting error.

    I think you need this https://jsonplaceholder.typicode.com/todos.

     import React, { useState, useEffect } from "react";
    
    function App() {
      const [dummyData, setDummyData] = useState([]);
    
      useEffect(() => {
        fetch("https://jsonplaceholder.typicode.com/todos")
          .then((res) => {
            return res.json();
          })
          .then((data) => {
            setDummyData(data);
          });
      }, []);
    
      return (
        <div className="App">
          {dummyData.map((d) => {
            return (
              <h1>
                {d.id} - {d.title}
              </h1>
            );
          })}
        </div>
      );
    }
    
    export default App;
    
    

    Demo