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

SolidJS + TypeScript 中如何为传入组件的Icon添加样式(不使用cloneElement且不通过外层包裹)

SolidJS + TypeScript 中如何为传入组件的Icon添加样式(不使用cloneElement且不通过外层包裹)

嘿,我刚好遇过类似的问题,在SolidJS里确实没法像React那样用cloneElement,不过咱们换个思路就能解决——别传已经渲染好的Icon元素,而是传Icon组件本身,这样就能在SettingButton里自由给它加任意Props了!

下面是具体的修改步骤:

1. 调整SettingButton的Props类型

首先把icon的类型从JSX.Element改成SolidJS的Component<IconProps>,因为你所有的Icon组件(比如IconUser)都符合IconProps的类型定义:

import { Component } from 'solid-js';
// 确保导入了你的IconProps类型

export const SettingButton = (props: {
    title: string;
    icon: Component<IconProps>; // 这里改为组件类型
    onPress: () => void;
}) => {
const { hovering, hoveringProps } = useHovering();
const responsive = useResponsiveV2();
const color = () => {
    if (hovering()) {
        return c.colors.text.secondary;
    }
    return c.colors.text.tertiary;
};

return (
    <button onClick={props.onPress} {...hoveringProps}>
      {/* 直接渲染传入的Icon组件,同时传递style属性 */}
      <props.icon style={{ color: color() }} />
      <span>{props.title}</span>
    </button>
);
};

2. 修改组件用法

现在不用传<IconUser />(已经实例化的元素),而是传IconUser这个组件本身:

<SettingButton title="Test" icon={IconUser} onPress={() => {}} />

3. (可选)支持传入带初始Props的Icon

如果有时候你需要给Icon传递自定义初始Props(比如额外的class),可以把icon的类型改成接收IconProps的函数,灵活性更高:

export const SettingButton = (props: {
    title: string;
    icon: (iconProps: IconProps) => JSX.Element;
    onPress: () => void;
}) => {
    // ... 其他逻辑不变
    return (
        <button onClick={props.onPress} {...hoveringProps}>
            <props.icon style={{ color: color() }} />
            <span>{props.title}</span>
        </button>
    );
};

// 用法示例:给IconUser传递自定义class
<SettingButton 
    title="Test" 
    icon={(iconProps) => <IconUser {...iconProps} class="custom-icon-class" />} 
    onPress={() => {}} 
/>

为什么这个方案可行?

在SolidJS里,如果你传的是<IconUser />,它是已经创建好的JSX元素,没法再修改它的Props(因为没有cloneElement)。但如果你传的是组件本身(或者返回JSX的函数),你就可以在父组件里调用它的时候,自由添加或覆盖Props——这里就是把style={{ color: color() }}传递给Icon组件,而你的基础Icon组件会把这个style传递给内部的svg标签,完美符合你的需求!

这样既不用外层包裹div,也不需要依赖cloneElement,完全是SolidJS的原生写法~

备注:内容来源于stack exchange,提问作者dehlen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 12:54:36