Home > Software engineering >  useEffect and useState to fetch API data
useEffect and useState to fetch API data

Time:08-02

I want to use useEffect(on mount) to fetch from API and store it in useState. Fetch API is used to get the data. The problem is when initial page loading and also when I reload the page, it outputs an error called test.map is not a function. Why this happening and how to avoid this ?

import { useEffect, useState } from 'react';
function App() {

  const[test, setTest] = useState({})
  useEffect(() => {
    testfunc()
  }, [])

  async function testfunc(){
      let api = await fetch('https://jsonplaceholder.typicode.com/users')
      let apijson = await api.json()
      setTest(apijson)
  }
  

  return (
    <div className="App">
      {
        test.map((item) => {
          return(
            <div>
              {item.name}
            </div>
          )
        })
      }
    </div>
  );
}

export default App;

CodePudding user response:

You can't map on an object {}, so you should need to define an array [] for the base state :

const[test, setTest] = useState([])

CodePudding user response:

As already mentioned, you can't use the .map for objects. Instead of this, you can make something like that

Object.keys(test).map(key => {
      const currentSmth = test[key]
      return(
        <div>
          {currentSmth.name}
        </div>
      )
    })
})

I think it helps you to solve your problem. Be careful using the correct data structures and methods.

CodePudding user response:

You have to change {} to array first to be able to map over it. You can easily place ? after test like this. or make in the default value of the state a default value for item name. because this error results as you map over an empty object.

import { useEffect, useState } from 'react';
function App() {

  const[test, setTest] = useState([{name:"default"}])
  useEffect(() => {
    testfunc()
  }, [])

  async function testfunc(){
      let api = await fetch('https://jsonplaceholder.typicode.com/users')
      let apijson = await api.json()
      setTest(apijson)
  }
  

  return (
    <div className="App">
      {
        test?.map((item) => {
          return(
            <div>
              {item.name}
            </div>
          )
        })
      }
    </div>
  );
}

export default App;
  • Related