-
Notifications
You must be signed in to change notification settings - Fork 547
Open
Description
实现withProps函数,用于提前注入组件属性。
import { ComponentProps, ComponentType, ForwardRefExoticComponent, forwardRef, memo } from 'react';
type ElementType = keyof JSX.IntrinsicElements | ComponentType;
type GetProps<C extends ElementType, E> =
| Partial<ComponentProps<C>>
| ((props: ComponentProps<C> & E) => Partial<ComponentProps<C>>);
export function withProps<C extends ElementType>(
Component: C,
): <EP = {}>(getProps: GetProps<C, EP>) => ForwardRefExoticComponent<ComponentProps<C> & EP> {
const Comp = Component as any; // Fixed "Expression produces a union type that is too complex to represent."
return (getProps) => {
return memo(
forwardRef((props: any, ref) => {
const injectedProps = typeof getProps === 'function' ? getProps(props) : getProps;
return <Comp ref={ref} {...props} {...injectedProps} />;
}),
);
};
}示例:
import { CSSProperties } from 'react';
type InputProps = {
type?: 'text' | 'password' | 'file';
value?: string;
style?: CSSProperties;
};
function Input(props: InputProps) {
return <input {...props} />;
}
const PasswordInput = withProps(Input)({ type: 'password' });
// const PasswordInput = withProps('input')({ type: 'password' });
const CustomInput = withProps(Input)<{ block?: boolean }>((props) => ({
style: props.block ? { display: 'block' } : undefined,
}));
const password = <PasswordInput value='123456' />
const custom = <CustomInput block value='hello' />