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
相关产品推荐
相关产品推荐

