You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.30 11:36:01