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

如何在React中用Tailwind实现带自定义Props的可复用组件

如何结合Tailwind实现支持自定义颜色和大小的可复用StarRating组件

你的代码里用了stroke-${color}这类动态拼接Tailwind类名的写法,但Tailwind的JIT编译器无法识别动态生成的类名,导致样式不生效。下面提供两种可行方案解决这个问题:


方案1:使用内联style属性(推荐,支持任意颜色值)

这种方式灵活性最高,不管传入的是Tailwind预设颜色名(如black)还是自定义十六进制/RGB颜色,都能直接生效。

修改后的StarRating组件

import { useState } from "react";
import Star from "./Star";

const StarRating = ({
  maxRating = 5,
  textColor = "black",
  starColor = "#fcc419", // 默认使用黄色星星
  emptyStarColor = "black",
  textSize = "xs",
  starSize = 5, // 支持数字(对应Tailwind的w/h类)或带单位字符串(如"1.5rem")
}) => {
  const [rating, setRating] = useState(0);
  const [tempRating, setTempRating] = useState(0);

  const onRateHandler = (rate) => setRating(rate);
  const onHoverInHandler = (rate) => setTempRating(rate);
  const onHoverOutHandler = () => setTempRating(0);

  return (
    <div className="flex flex-row justify-center items-center gap-x-4 p-8">
      <div className="flex flex-row justify-center items-center gap-x-3">
        {Array.from({ length: maxRating }, (_, i) => (
          <Star
            key={i}
            onRate={() => onRateHandler(i + 1)}
            full={tempRating ? tempRating >= i + 1 : rating >= i + 1}
            hoverIn={() => onHoverInHandler(i + 1)}
            hoverOut={onHoverOutHandler}
            starColor={starColor}
            emptyStarColor={emptyStarColor}
            size={starSize}
          />
        ))}
      </div>
      {/* 用style属性设置文本颜色,支持任意值 */}
      <p className={`text-${textSize}`} style={{ color: textColor }}>
        {tempRating || rating || ""}
      </p>
    </div>
  );
};

export default StarRating;

修改后的Star组件

const Star = ({ onRate, full, hoverIn, hoverOut, starColor, emptyStarColor, size }) => {
  // 处理size:数字对应Tailwind的w/h类,字符串直接用任意值语法
  const sizeClass = typeof size === 'number' ? `w-${size} h-${size}` : `w-[${size}] h-[${size}]`;

  return (
    <span
      role="button"
      className="cursor-pointer block"
      onClick={onRate}
      onMouseEnter={hoverIn}
      onMouseLeave={hoverOut}
    >
      {full ? (
        <svg
          xmlns="http://www.w3.org/2000/svg"
          viewBox="0 0 20 20"
          className={sizeClass}
          style={{ stroke: starColor, fill: starColor }}
        >
          <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
        </svg>
      ) : (
        <svg
          xmlns="http://www.w3.org/2000/svg"
          viewBox="0 0 20 20"
          className={`${sizeClass} fill-none`}
          style={{ stroke: emptyStarColor }}
        >
          <path
            strokeLinecap="round"
            strokeLinejoin="round"
            strokeWidth="2"
            d="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z"
          />
        </svg>
      )}
    </span>
  );
};

export default Star;

方案2:使用Tailwind任意值语法(适合熟悉Tailwind规则的场景)

如果想坚持用Tailwind类名,可以用它的任意值语法(如stroke-[#fcc419]),但需要注意以下细节:

修改Star组件的类名部分

// 选中的星星
<svg
  xmlns="http://www.w3.org/2000/svg"
  viewBox="0 0 20 20"
  className={`w-${size} h-${size} stroke-[${starColor}] fill-[${starColor}]`}
>
  {/* path内容 */}
</svg>

// 未选中的星星
<svg
  xmlns="http://www.w3.org/2000/svg"
  viewBox="0 0 20 20"
  className={`w-${size} h-${size} fill-none stroke-[${emptyStarColor}]`}
>
  {/* path内容 */}
</svg>

补充配置

为了确保动态类名被Tailwind编译,建议在tailwind.config.js中添加安全列表:

module.exports = {
  safelist: [
    { pattern: /stroke-.+/ },
    { pattern: /fill-.+/ },
    { pattern: /w-.+/ },
    { pattern: /h-.+/ },
  ],
}

使用示例

现在你可以轻松复用这个组件:

// 自定义黄色星星,大小为6,文本颜色为深灰
<StarRating starColor="#fcc419" starSize={6} textColor="gray-700" textSize="sm" />

// 10星评分,蓝色填充星+浅蓝空心星
<StarRating starColor="blue-500" emptyStarColor="blue-200" maxRating={10} />

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 16:54:50