React JS遍历state商品时报products.map is not a function错误
报错原因
TypeError: products.map is not a function的直接触发原因是:初始化为数组的products状态,被错误赋值为普通对象,对象不存在map方法。结合现有代码,具体的问题点如下:
- 状态赋值逻辑错误:fetch回调中执行
setProducts({product}),将响应对象包裹为键名为product的普通对象,完全替换了初始的数组结构 - 响应解析流程缺失:fetch接口返回的是原始Response流对象,未经过
.json()解析就直接赋值,根本无法拿到接口返回的商品列表数组 - 无效请求配置:
mode: 'no-cors'会让响应变为不透明的无效结构,前端无法读取返回的实际数据。跨域问题需要后端配置CORS响应头解决,前端添加no-cors配置无法获取有效数据 - 副作用逻辑位置错误:fetch请求直接写在组件函数体内,每次组件重渲染都会触发重复请求,且没有异常捕获,请求失败时无任何反馈
- 渲染缺少兜底逻辑:未对
products的类型做校验,非数组状态下直接执行map会直接触发崩溃;同时map遍历列表项未添加唯一key属性,会触发React渲染警告
修复操作
- 移除多余的
no-cors请求配置,删除会将状态转为对象的赋值逻辑 - 将fetch请求逻辑迁移到
useEffect钩子中,组件挂载后仅执行一次,避免重复请求;链式调用.json()解析响应数据,补充请求异常捕获逻辑 - 渲染前增加类型判断,仅当
products为有效数组时才执行map遍历;为每个列表项添加唯一key属性,消除渲染警告
修复后代码
import React, { useState, useEffect } from 'react' import { Card } from 'react-bootstrap' function HomeScreen() { const [products, setProducts] = useState([]) const [loadError, setLoadError] = useState(null) // 组件挂载后执行一次商品请求 useEffect(() => { const requestConfig = { method: 'GET', headers: { 'Content-Type': 'application/json' } } fetch('http://localhost:8000/api/products/', requestConfig) .then(response => { if (!response.ok) throw new Error('商品接口请求异常') return response.json() }) // 接口返回数组类型数据时才赋值,否则置为空数组兜底 .then(data => setProducts(Array.isArray(data) ? data : [])) .catch(err => setLoadError(err.message)) }, []) // 加载异常时优先展示错误提示 if (loadError) return <div>{loadError}</div> return ( <div> {Array.isArray(products) && products.map(product => ( // 补充唯一key,使用商品id即可,根据实际接口字段调整 <Card key={product._id} className="my-3 p-3 rounded"> <Card.Img src={product.image} /> <Card.Body> <Card.Title as="div"> <strong>{product.name}</strong> </Card.Title> <Card.Text as="div"> </Card.Text> <Card.Text as="h3"> ${product.price} </Card.Text> </Card.Body> </Card> ))} </div> ) } export default HomeScreen
内容的提问来源于stack exchange,提问作者user14414828
相关产品推荐
相关产品推荐

