谁能解释为什么我收到地图函数错误

rnd*_* om 3 javascript fetch reactjs next.js

我正在尝试了解 api 获取,并且我遵循了这里的其他一些答案,但是我在这个脚本上不断收到一个奇怪的错误:

const fetcher = async () => {
    const url = 'https://banana1.free.beeceptor.com/cars'
    const response = await fetch(url) //once we fetch we get a resposne
    const json_data = await response.json()
    return json_data
}

const Publish = () => {
    const [loading, setLoading] = useState(true)
    const [choices, setChoices] = useState([])

    useEffect(()=>{
        const choiceGetter = async () => {
            await fetcher().then(json_data=>{
                setChoices(json_data);
                setLoading(false);
                console.log(json_data)
            })
        };
        choiceGetter();
    },[])

    return(
        <>
        <h1>
            {loading&&<>loading...</>}
            {!loading&&choices&&
                choices.map( (choice) => {
                    const {option,make} = choice;
                    return( <div key={car1}>
                            <h1>{option}</h1>
                            <h3>{make}</h3>
                            </div>)
                } )
            }
        </h1>
        </>
    )
}
export default ApiTest
Run Code Online (Sandbox Code Playgroud)

错误:

Unhandled Runtime Error
TypeError: choices.map is not a function

Source
.next/static/chunks/pages/index.js (56:24) @ ApiTest

  54 | {loading&&<>loading...</>}
  55 | {!loading&&choices&&
> 56 |     choices.map( (choice) => {
     |            ^
  57 |         const {option,make} = choice;
  58 |         return( <div key={car1}>
  59 |                 <h1>{option}</h1>
Run Code Online (Sandbox Code Playgroud)

我什至尝试模仿以下内容:

ReactJs useState .map() 不是函数

但它不工作...

Dre*_*ese 5

问题

响应不是一个数组,而是一个对象。

// 20211006212847
// https://banana1.free.beeceptor.com/cars

{
  "car1": {
    "option": "lease",
    "make": "toyota",
    "body": "round",
    "model": "camery",
    "trim": "sle",
    "year": 2020,
    "color": "metalic gray"
  },
  "car2": {
    "option": "finance",
    "make": "nissan",
    "body": "square",
    "model": "sentra",
    "trim": "xle",
    "year": 2021,
    "color": "army green"
  }
}
Run Code Online (Sandbox Code Playgroud)

所以choices状态不是一个数组。你正在改变状态不变量。

解决方案

渲染时将其转换为数组:

Object.values(choices).map(choice => ....
Run Code Online (Sandbox Code Playgroud)

或者在状态存储时进行转换:

useEffect(()=>{
  fetcher().then(json_data => {
    setChoices(Object.values(json_data));
    setLoading(false);
  });
},[]);
Run Code Online (Sandbox Code Playgroud)

更新

如果您想使用对象的键(即“car”、“car2”等),则使用Object.entries返回键值对数组。

Object.entries(choices).map(([key, choice]) => {
  const {option, make} = choice;
  return (
    <div key={key}>
      <h1>{option}</h1>
      <h3>{make}</h3>
    </div>
  )
})
Run Code Online (Sandbox Code Playgroud)