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

React自定义组件InfoCard:无需CSS类为Icon设置不同颜色

不用CSS类给InfoCard的Icon设置不同颜色的可行方案

当然可以不用CSS类实现这个需求,结合你使用的Material-UI,这里提供几种实用的实现方式:

方案一:直接在传入的Icon组件上添加sx属性

你使用的MUI图标组件(如ArrowDownIcon)本身支持sx属性,调用InfoCard时直接给目标图标设置颜色即可,这是最直接的方式:

修改Header组件中的代码:

const Header = () => {
  const { t } = useTranslation()
  return (
    <Box>
      <Grid container>
        <Grid item xs={12} sm={12} md={6} lg={4}>
          <InfoCard
            icon={<ArrowDownIcon className="smallIcon" sx={{ color: '#f44336' }} />} {/* 红色 */}
            title={t('LOWEST_REGULAR_PRICE')}
            store="store 1"
            price="1.900"
            divider={<Divider orientation="vertical" />}
          />
        </Grid>
        <Grid item xs={12} sm={12} md={6} lg={4}>
          <InfoCard
            icon={<ArrowTrendingUpIcon className="smallIcon" sx={{ color: '#4caf50' }} />} {/* 绿色 */}
            title={t('AVERAGE_REGULAR_PRICE')}
            price="1.900"
          />
        </Grid>
        <Grid item xs={12} sm={12} md={12} lg={4}>
          <InfoCard
            icon={<ArrowPathIcon className="smallIcon" sx={{ color: '#9e9e9e' }} />} {/* 灰色 */}
            title={t('LAST_UPDATE')}
            price="19/07/2022"
          />
        </Grid>
      </Grid>
    </Box>
  )
}

方案二:扩展InfoCard的Props,统一在组件内部控制颜色

如果希望在InfoCard层面统一管理图标颜色,避免重复编写样式,可以新增一个iconColor属性,通过React.cloneElement修改传入图标的属性:

首先修改InfoCard的Props和组件逻辑:

import React from 'react';

interface Props {
  icon: JSX.Element
  title: string
  store?: string
  price: string
  divider?: JSX.Element
  iconColor?: string // 新增颜色属性
}

// ... 保留Item的styled代码不变

const InfoCard = ({ icon, title, store, price, divider, iconColor }: Props) => {
  // 克隆图标组件并添加颜色样式
  const coloredIcon = React.cloneElement(icon, {
    sx: {
      ...icon.props.sx, // 保留原有的sx属性
      color: iconColor || icon.props.sx?.color // 优先使用传入的iconColor
    }
  });

  return (
    <>
      <Item>
        <Stack direction="row" spacing={2} sx={{ justifyContent: 'center' }}>
          <Box>{coloredIcon}</Box> {/* 渲染修改后的图标 */}
          <Typography>{title}</Typography>
          <Box>{divider}</Box>
          <Typography>{store}</Typography>
        </Stack>
        <Typography variant="h5" sx={{ color: 'primary.main' }}>
          {price}
        </Typography>
      </Item>
    </>
  )
}

export default InfoCard

然后在Header中调用时只需传入iconColor:

const Header = () => {
  const { t } = useTranslation()
  return (
    <Box>
      <Grid container>
        <Grid item xs={12} sm={12} md={6} lg={4}>
          <InfoCard
            icon={<ArrowDownIcon className="smallIcon" />}
            iconColor="#f44336"
            title={t('LOWEST_REGULAR_PRICE')}
            store="store 1"
            price="1.900"
            divider={<Divider orientation="vertical" />}
          />
        </Grid>
        <Grid item xs={12} sm={12} md={6} lg={4}>
          <InfoCard
            icon={<ArrowTrendingUpIcon className="smallIcon" />}
            iconColor="#4caf50"
            title={t('AVERAGE_REGULAR_PRICE')}
            price="1.900"
          />
        </Grid>
      </Grid>
    </Box>
  )
}

方案三:直接使用inline style属性

如果你的图标不是MUI组件,或者更倾向于原生inline style,直接给图标添加style属性也能生效:

<InfoCard
  icon={<ArrowDownIcon className="smallIcon" style={{ color: 'red' }} />}
  // ... 其他属性
/>

总结

  • 如果你只需要给个别图标设置颜色,方案一最简洁高效;
  • 如果需要批量控制或复用颜色逻辑,方案二更适合;
  • 方案三是通用兼容方案,适用于所有React元素。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 12:01:20