React请求API后调用lights.map报错TypeError: lights.map is not a function
问题原因与解决方案
错误根因
- 核心本质是当前
lights变量不是数组类型,只有数组实例才拥有map遍历方法,非数组类型调用该方法就会抛出该错误,常见触发场景有两种:- API返回的
res.data本身不是数组:很多后端接口会把列表数据包裹在响应对象的子字段中,或是部分接口(比如飞利浦Hue的灯光查询接口)直接返回键值对格式的对象,键为灯光ID、值为灯光详情,不是数组结构,直接赋值给lights就会导致类型错误。 lights的初始值错误:如果使用useState定义lights时,初始值设置为undefined、null、{}等非数组类型,页面首次渲染时还未触发接口请求,就会直接调用map方法报错。
- API返回的
修复步骤
- 修正状态初始值
首先确保useState给lights设置数组类型的初始值:
import { useState } from 'react' // 初始值设为空数组 const [lights, setLights] = useState([])
- 适配接口返回结构
先查看控制台打印的res.data结构,如果是对象格式,将其转为数组后再赋值给状态,如果是嵌套在响应对象的子字段中,取对应字段的值即可:
function getLight(){ Axios.get('http://{IP}/api/{KEY}/lights').then((res) =>{ console.log(res.data) // 若res.data是键值对对象,用Object.values转成数组 const lightList = Object.values(res.data) // 若列表嵌套在res.data的子字段比如result/list中,就改为 res.data.result 之类的对应取值 setLights(lightList) }) }
- 渲染时增加类型兼容判断
可以用可选链或者数组类型判断,避免极端情况报错:
<button onClick={getLight}>Lights 1</button> <div> {/* 可选链写法,非数组时返回undefined不渲染 */} {lights?.map((light) => <li key={light.id}>{light.name}</li>)} {/* 也可以用Array.isArray判断 {Array.isArray(lights) && lights.map((light) => <li key={light.id}>{light.name}</li>)} */} </div>
注意:遍历渲染列表元素时需要给每个子项加唯一
key属性,避免React抛出列表key相关警告。
内容的提问来源于stack exchange,提问作者user14141591
相关产品推荐
相关产品推荐

