- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
在 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/
typescript 抛出: Cannot use JSX unless the '--jsx' flag is provided.ts(17004) 更改后tsconfig.json jsx至 re
我正在尝试使用 JSX 表达式作为另一个 JSX 表达式的生成主体的一部分: render() { return ( {[...Array(5).keys()].
eslint jsx-quotes 规则在 Visual Studio 代码中不起作用。配置: .eslintrc.json: { "plugins": ["jsx"], "parse
如果我声明 var A = new Set(...........); var B = new Set(...........); 是否有 JSX 操作来计算两组 A - B 的差异? 最佳答案
这个问题在这里已经有了答案: How to render react components by using map and join? (18 个答案) 关闭 5 年前。 我遇到过这样的情况,我有
完成执行另一个 .jsx 脚本后,如何让我的 .jsx 脚本? 也许这将有助于理解我正在尝试做的事情: // WebCard.jsx file function mySnippet(){ //
JSX 不允许多次指定一个属性。 F.ex. /* /* where obj contains an attribute called "prop1" */ 属性的顺
我在尝试使用循环数组构建自定义组件时遇到问题,该循环数组有条件地呈现不同的元素。该组件包含特殊的类名,用于生成每行 3 个元素的网格,与传递给组件的参数数量无关。 我正在使用 map用于遍历条件索引,
我有一个要从 JS 转换为 TS 的 React 项目。我遇到的一个问题是 TSX React 假设功能组件中定义的所有属性都是必需的 Prop 。 // ComponentA.tsx class C
我有一个通过数组映射的 React 组件。 每个数组项都有一个可选的 ID 类型。 如果我有这个 ID,我将渲染一个元素,否则什么都不渲染。 这个元素有一个 onClick 调用函数接受 ID 作为参
我目前正在编写一个带有 ref 元素的 StencilJS 组件,我需要将其作为 @Prop 传递给另一个元素。像这样: this.canvas = el}> 创建颜色选择器时,this.canv
我正在尝试将对象传递给 react 中的 jsx 标记的值 我将标签选项的值设置为一个对象 onChange 我得到了标签 中的值并用值设置本地状态 我控制台记录了本地状态,但它返回了 [objec
我正在尝试使用 Chart.js 和 Typescript 在 React 中构建应用程序,但是当尝试渲染折线图时,我在这一行收到上述错误: . 除此之外,我还收到消息“类型‘ChartCompone
我正在使用一个变量来有条件地显示不同的 JSX,并且它没有使用在其父函数中定义的样式。我怎样才能做到这一点? 您可以在此处查看演示:https://codesandbox.io/s/styled-js
使用 Nextjs 和 styled-jsx 我编写了下面的组件。 现在我想知道如何将 styled-jsx 应用于从 getLinks 方法返回的 jsx。 在下面的示例中,来自 getLinks
所以我现在的问题是,如果我有一个 JSX 父组件,但我需要包含一个 html 标签,例如 我认为 React JSX 不支持它(如果我错了请纠正我)我可以混合使用 jsx 和非 jsx 组件吗?我个人
我正在编写一个 react 应用程序来从嵌套对象数组中打印 TreeView 。每个节点都应该是可折叠的(默认打开)。一个节点可以有任意数量的子节点。这是我想要实现的示例: 我正在将所有节点组件收集到
它不是 React 项目,也不是 V-DOM 相关的。我只需要一个 jsx 运行时编译器到 (HTML/XML) 字符串,稍后将用作 element.innerHTML = result 它应该用作支
当 jsx 跨越多行时,哪种 eslint 规则更喜欢前者而不是后者?目前 prettier 正在从 preferred 变为 notPreferred const preferred = (
我正在使用 IDEA 2017.2。我需要设置 JSX codestyle,这样大括号之间就有空格,比如 { event.series } 。但是,它会将其自动格式化为 {event.series}
我是一名优秀的程序员,十分优秀!