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

React使用this.state渲染组件时出现元素类型无效报错

React Invalid Element Type 报错修复方案

控制台报错信息

  • 警告:React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: array,提示检查ButtonMenu.js第432行代码
  • 错误:Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object

问题根因

报错由命名混淆直接触发,附带1个逻辑bug:

  1. 代码中定义的ProductList是存储产品条目的普通JavaScript数组,并非React组件,但render方法中直接以JSX标签形式书写了<ProductList products={this.state.products} />
  2. JSX解析规则明确要求:大写开头的标签会被识别为自定义组件,对应值必须是函数/类形式的合法组件定义;小写开头的标签会被识别为原生HTML标签,对应值必须是字符串类型的标签名。此处传入数组类型,完全不符合类型要求,直接抛出类型无效错误。
  3. 现有分类过滤逻辑未处理All选项,点击全部分类时会匹配不到任何数据,返回空数组导致列表空白。

修复方案

按以下步骤调整代码即可解决问题:

  • 将存储原始产品数据的数组重命名为PRODUCT_DATA,和组件名做明确区分,常量使用全大写命名也符合通用编码规范
  • 定义合法的ProductList函数组件,接收products属性,遍历传入的产品数组渲染列表UI
  • 修正分类过滤逻辑,点击「All」选项时直接返回全量产品数据,其余分类按category字段做匹配过滤

修复后的完整代码如下:

import React, {Component} from "react";  

// 重命名原产品数据数组,与组件名做区分
const PRODUCT_DATA = [
    {
        id:0,
        category:"accessories",
        image:"./prod_images/accessory1.jpg",
        product: "product1",
        description: "product1",
        price: 0.00
    },
    // 此处保留原有50+个产品对象即可
];

const CATEGORIES = ['All', 'Men', 'Women', 'Jerseys', 'Shirts', 'Accessories', 'Collectables'];

// 定义合法的ProductList组件
const ProductList = (props) => {
    const { products } = props;
    return (
        <div className="product-list-wrap">
            {products.map(productItem => (
                <div key={productItem.id} className="product-card">
                    <img src={productItem.image} alt={productItem.product} />
                    <h4>{productItem.product}</h4>
                    <p>{productItem.description}</p>
                    <p className="price">${productItem.price.toFixed(2)}</p>
                </div>
            ))}
        </div>
    )
}

class ButtonMenu extends Component {
    constructor(props) {
      super(props);
      this.state = {
        products: PRODUCT_DATA
      };
    }
  
    getCategory = category => {
      // 处理全部分类的逻辑
      if (category === 'all') {
        this.setState({products: PRODUCT_DATA});
        return;
      }
      const filteredList = PRODUCT_DATA.filter(item => item.category.toLowerCase() === category);
      this.setState({products: filteredList});
    };

    render() {
      return (
       <>
          <div className="button Menu-container">
            <ProductList products={this.state.products} />
            {CATEGORIES.map(item => (
                <button
                key ={item.toString()}
                className="main-btn"
                onClick={() => this.getCategory(item.toLowerCase())}
                value={item.toLowerCase()}>
                {item}
              </button>
            ))}
          </div>
          </>
      );
    }
  }
  
  export default ButtonMenu;

注意:编写JSX时需要严格区分普通数据变量和组件变量,所有作为标签使用的大写开头变量,必须是合法的React组件定义,禁止将数组、普通对象、字符串等非组件类型作为JSX标签使用。

内容的提问来源于stack exchange,提问作者madQuestions

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 04:21:14