这一期CodeSandbox Example美元.
我已经定义了一个图标库,它可以导出几个图标.每个Icon将一个引用转发到其内部SVG.下面是一个例子:
type ReactIconProps = SVGProps<SVGSVGElement>;
function CheckIconInner(props: ReactIconProps, ref: Ref<SVGSVGElement>) {
return (
<svg
fill="none"
height="1em"
ref={ref}
stroke="currentColor"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
d="M20 6L9 17L4 12"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
/>
</svg>
);
}
const CheckIcon = forwardRef(CheckIconInner);
我想将这些图标用作按钮组件中的props ,以便按钮可以包含图标.请参见下面的内容:
type ReactButtonProps = ButtonHTMLAttributes<HTMLButtonElement>;
export interface ButtonProps extends ReactButtonProps {
Icon?: ComponentType<ReactIconProps>;
}
function Button({ children, Icon, ...props }: ButtonProps) {
return (
<button {...props}>
{Icon !== undefined && <Icon />}
{children}
</button>
);
}
export default function App() {
return <Button Icon={CheckIcon}>OK</Button>;
}
然而,当图标被传递给按钮(<Button Icon={CheckIcon}>OK</Button>
)时,该方法抛出打字错误:
TS2322: Type 'ForwardRefExoticComponent<Omit<ReactIconProps, "ref"> & RefAttributes<SVGSVGElement>>' is not assignable to type 'ComponentType<ReactIconProps> | undefined'.
Type 'ForwardRefExoticComponent<Omit<ReactIconProps, "ref"> & RefAttributes<SVGSVGElement>>' is not assignable to type 'FunctionComponent<ReactIconProps>'.
Types of parameters 'props' and 'props' are incompatible.
Type 'ReactIconProps' is not assignable to type 'Omit<ReactIconProps, "ref"> & RefAttributes<SVGSVGElement>'.
Type 'SVGProps<SVGSVGElement>' is not assignable to type 'RefAttributes<SVGSVGElement>'.
Types of property 'ref' are incompatible.
Type 'LegacyRef<SVGSVGElement> | undefined' is not assignable to type 'Ref<SVGSVGElement> | undefined'.
Type 'string' is not assignable to type 'Ref<SVGSVGElement> | undefined'.
问题是,图标需要一个裁判,但我们没有给它传一个.
两个问题:
- 如何指定传递给icon组件的ref是可选的?
- 在图标组件中使用ref是一种好做法吗?我看到了很多关于引用不应该被过度使用的建议,但也看到了组件库可能会广泛使用它.
Edit个
我在an issue in the heroicons repository个用例中找到了2号的答案--大量的用例!