reactjs - 如何在 React 高阶组件中输入 defaultProps
问题描述
我的高阶组件无法识别在传递的组件中实现的 defaultProps。我怎样才能正确输入这个?
这是一个基本示例:
import React from 'react';
// HOC
const withTheme = <P extends {}>(Comp: React.ComponentType<P>) => {
return Comp as React.ComponentType<P> & {
defaultProps: typeof Comp['defaultProps'];
};
}
class Button extends React.Component<{size: string }> {
static defaultProps = {
size: 'l'
}
}
const ThemedButton = withTheme(Button)
// here's the problem:
// left-hand side is Partial or undefined
// right-hand side is defined, but `withTheme` can't infer it
ThemedButton.defaultProps = Button.defaultProps;
// Button works fine
const a = () => <Button />
// ThemedButton does not work fine
const b = () => <ThemedButton />
有没有推荐的方法来使用这些道具并正确输入?
解决方案
也许这符合您的要求。看起来有点复杂,因为defaultProps
类型真的很难从Button
. 最后我尝试了很多东西,结果如下:
const withTheme = <
C extends React.ComponentType<any>, // Component type
T, // Default theme props type
Props = C extends React.ComponentType<infer R> ? R : never // Props type
>(
Comp: C,
defaultProps?: T extends Partial<Props> ? T : never
) => {
return (
props: Omit<Props, keyof (typeof Comp['defaultProps'] & T)> &
Partial<typeof Comp['defaultProps'] & T> &
JSX.LibraryManagedAttributes<C, { children?: ReactNode }>
) => <Comp {...defaultProps} {...props} />;
};
class Button extends React.Component<{
size: string;
id: number;
theme: string;
}> {
static defaultProps = {
size: 'small',
};
}
const a0 = () => <Button id={1} />; // Error
const b0 = () => <Button id={1} theme="dark" />; // OK
const ThemeButton1 = withTheme(Button);
const a1 = () => <ThemeButton1 id={1} />; // Error
const b1 = () => <ThemeButton1 id={1} theme="dark" />; // OK
const ThemeButton2 = withTheme(Button, {
theme: 'dark',
});
const a2 = () => <ThemeButton2 />; // Error
const b2 = () => <ThemeButton2 id={1} />; // OK
更新前
也许你可以试试,还有其他更好的选择让它不使用as
// change
typeof Comp['defaultProps']
// into
Partial<P>
推荐阅读
- c++ - 7zip 构建失败并出现 LzFind.c(1613,30):错误 C2440:void (__stdcall *)(UInt32,CLzRef *,const CLzRef *)”->“LZFIND_SATUR_SUB_CODE_FUNC
- android - SetUpAndroid 失败,说命令拼写错误或找不到
- android - Android Gradle 离线模式会在每次构建后自动启用
- vuejs2 - Vue2 onServerPrefetch 在没有与 apollo 关联的活动组件实例时调用
- flutter - 如何在颤动中将状态栏图标颜色更改为白色
- javascript - SPA中如何保护路由?
- datastax-astra - 无法从 Datastax Astra DB 中获取所有行
- angular - 如何在谷歌地图上为角度设置聚集标记的 z 索引?
- python - 加速遍历大型数组的循环的方法
- pyspark - Pyspark:如何保存和应用 IndexToString 以将标签转换回新预测数据集中的原始值