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

直接返回React组件失效,React.cloneElement生效的问题排查

React-Bootstrap-Icons 直接渲染报错问题解决

问题描述

我想根据API返回的文件类型构建一个可条件渲染的图标字典,但在FileIconMapper.jsx里直接返回<Icon size="40px" color="red" />时触发错误:

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
Check the render method of FileIconMapper.

只有用React.cloneElement(Icon)才能正常渲染,其他React组件不用克隆就能正常工作。我怀疑是react-bootstrap-icons库的问题,试过用{}包裹渲染也没用。

项目依赖配置:

{
...
  "dependencies": {
    "next": "^13.2.3",
    "react": "18.2.0",
    "react-bootstrap": "^2.7.2",
    "react-bootstrap-icons": "^1.10.2",
    "react-datepicker": "^4.10.0",
    "react-dom": "18.2.0",
    "react-select": "^5.7.0",
  },
...
}

问题原因

react-bootstrap-icons导出的图标并不是标准的React组件函数/类,而是已经实例化的React元素对象,不是可直接调用的组件类型。直接用JSX语法<Icon />相当于尝试渲染一个对象,而非组件,所以触发报错。

解决方案

方案1:存储组件本身,渲染时传入props

把图标组件(而非实例化后的元素)存入字典,渲染时再通过JSX语法传入size、color等属性:

import { FileText, Image, Pdf } from 'react-bootstrap-icons';

// 字典存储组件类型
const iconMap = {
  txt: FileText,
  img: Image,
  pdf: Pdf
};

const FileIconMapper = ({ fileType }) => {
  const IconComponent = iconMap[fileType];
  // 存在对应组件则渲染,否则返回null
  return IconComponent ? <IconComponent size="40px" color="red" /> : null;
};

方案2:用React.cloneElement复用已配置的元素实例

如果需要提前配置好图标属性并存入字典,就用React.cloneElement来克隆已有的元素实例进行渲染:

import { FileText, Image } from 'react-bootstrap-icons';
import React from 'react';

// 字典存储已配置好的元素实例
const iconMap = {
  txt: <FileText size="40px" color="red" />,
  img: <Image size="40px" color="blue" />
};

const FileIconMapper = ({ fileType }) => {
  const iconElement = iconMap[fileType];
  return iconElement ? React.cloneElement(iconElement) : null;
};

为什么其他组件没问题?

其他React组件(比如自定义组件、react-bootstrap的内置组件)导出的是组件类或函数,属于可直接调用的组件类型,因此可以直接用<Component />的JSX语法渲染,不需要克隆。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 16:42:49