有什么方法可以在React.memo中设置新的泛型吗?
例如,对于类组件,我可以使用
// set generic
class GenericClass<G extends string | number> extends PureComponent {}
// and use like this
<GenericClass<number> />
在以下情况下,我要使G型成为通用类型。
type G = string;
const MemoComponent = memo<{ value: G; onValueChange: (newValue: G) => void }>(
({ value, onValueChange }) => {
return (
<select
onClick={() => {
// do calculation
onValueChange(value);
}}
>
Button
</button>
);
}
);
我想知道也可以在React.memo中设置泛型吗?例如,如下所示
const MemoComponent = <G extends string | number | object>React.memo<{value: G}>(({value}) => component)
// and use like this
<MemoComponent<number> />
答案 0 :(得分:15)
我遇到了同样的问题,并像这样解决了。
interface ISomeComponentWithGenericsProps<T> { value: T; }
function SomeComponentWithGenerics<T>(props: ISomeComponentWithGenericsProps<T>) {
return <span>{props.value}</span>;
}
export default React.memo(SomeComponentWithGenerics) as typeof SomeComponentWithGenerics;
答案 1 :(得分:2)
更新(贷记到@ Ryan1729的问题提示):
tl; dr:
当前not possible与generic type arguments结合使用React.memo
。 TypeScript无法保留传入的泛型组件(本质上是一个功能接口)的免费泛型类型参数,因此在调用React.memo
时,我们必须提供一个具体的参数。
说明:
该问题的一般示例在above issue中给出:
function identity<T>(arg: T) { return arg; }
function memoize<F extends (...args: unknown[]) => unknown>(fn: F): F { return fn; }
// memid: unknown => unknown
// desired: memid<T>(T) => T
const memid = memoize(identity);
现在,当您查看React.memo
的类型签名时,您会发现它是一个HOC,它返回某种内部Component类型,并带有由您的props产生的泛型类型参数。输入组件:
// Component: SFC<P> and NamedExoticComponent<P> are nothing more than
// functional generic interfaces, we can interpret `React.memo` as a
// generic higher order function.
function memo<P extends object>(Component: SFC<P>, ...): NamedExoticComponent<P>;
interface ExoticComponent<P = {}> {
...
(props: P): (ReactElement|null);
...
}
不幸的是,TypeScript无法保留由SFC<P>
产生的自由类型参数:
const Comp = <T extends {}>(props: {foo: T}) => {...};
// we do not provide concrete type parameter for Comp
const HOC = React.memo(Comp);
// doesn't work :/
const App = <HOC<string> />;
替代
1。)如果确实需要,可以将memo
包装在另一个HOC中,但是不能在JSX中设置通用类型参数。
type MemoComponentProps<G> = { ... }
const createMemoComponent = <G extends string | number | object>() =>
React.memo((props: MemoComponentProps<G>) => { ... })
const MemoComponent = createMemoComponent<number>();
2。)不要使用React.memo
并切换到useMemo
钩在输入组件内部。