gpt4 book ai didi

reactjs - 带有 withStyles 的 JSX 元素中的通用类型参数

转载 作者:搜寻专家 更新时间:2023-10-30 21:06:24 25 4
gpt4 key购买 nike

在 React with material-ui 中,我尝试创建一个 JSX 组件,它接受通用参数并使用 withStyles HOC 来注入(inject)我的样式。

第一种方法是这样的:

const styles = (theme: Theme) => createStyles({
card: {
...
}
});

interface Props<T> {
prop: keyof T,
...
}

type PropsWithStyles<T> = Props<T> & WithStyles<typeof styles>;

export default withStyles(styles)(
class BaseFormCard<T> extends React.Component<PropsWithStyles<T>> {
...
}
),

但是当尝试使用它时,泛型类型丢失了

<BaseFormCard<MyClass> prop={ /* no typings here */ } />

我能找到的唯一解决方案是将导出包装在一个函数中,该函数采用通用参数并构造组件。

export default function WrappedBaseFormCard<T>(props: Props<T>): ReactElement<Props<T>> {

const wrapper = withStyles(styles)(
class BaseFormCard<T> extends React.Component<PropsWithStyles<T>> {
...
}
) as any;

return React.createElement(wrapper, props);
}

然而,这非常复杂,甚至会带来运行时成本,尽管它只是试图解决输入问题。

必须有更好的方法来使用具有通用参数和 HOC 的 JSX 组件。

这与这里的问题密切相关https://github.com/mui-org/material-ui/issues/11921 , 但一直没有令人满意的解决方案,问题现已关闭。

最佳答案

问题越想越喜欢Frank Li's approach .我会做两个修改:(1)引入一个额外的 SFC 以避免强制转换,以及(2)从包装组件中获取外部 Prop 类型 C而不是对其进行硬编码。 (如果我们对 Props<T> 进行硬编码,TypeScript 至少会检查它是否与 this.C 兼容,但我们有可能需要 this.C 实际上不需要或失败的 Prop 接受 this.C 实际接受的可选 Prop 。)从 extends 中的类型参数引用属性类型令人瞠目结舌。子句有效,但它似乎有效!

class WrappedBaseFormCard<T> extends React.Component<
// Or `PropsOf<WrappedBaseFormCard<T>["C"]>` from @material-ui/core if you don't mind the dependency.
WrappedBaseFormCard<T>["C"] extends React.ComponentType<infer P> ? P : never,
{}> {
private readonly C = withStyles(styles)(
// JSX.LibraryManagedAttributes handles defaultProps, etc. If you don't
// need that, you can use `BaseFormCard<T>["props"]` or hard-code the props type.
(props: JSX.LibraryManagedAttributes<typeof BaseFormCard, BaseFormCard<T>["props"]>) =>
<BaseFormCard<T> {...props} />);
render() {
return <this.C {...this.props} />;
}
}

我认为任何关于这种方法的运行时开销的提示在整个 React 应用程序的上下文中都可能是无稽之谈;当有人提供支持他们的数据时,我会相信他们。

请注意,Lukas Zech 使用 SFC 的方法非常不同:每次外部 SFC 的 Prop 发生变化并再次调用时,withStyles再次调用,生成 wrapper在 React 看来就像一个全新的组件类型,所以 React 扔掉了旧的 wrapper实例和一个新的内部 BaseFormCard组件被创建。这会产生不良的行为(重置状态),更不用说更大的运行时开销了。 (我还没有真正测试过这个,所以如果我遗漏了什么,请告诉我。)

关于reactjs - 带有 withStyles 的 JSX 元素中的通用类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52567697/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com