我可以直接从React中的JSX/TSX内部调用HOC吗?
我在TypeScript中有一个React HOC,但当我从TSX组件render
方法中调用它时似乎不起作用。这里有一个例子:我可以直接从React中的JSX/TSX内部调用HOC吗?
export class HelloWorldComponent extends React.Component<{}, {}> {
public render(): JSX.Element {
return <div>Hello, world!</div>;
}
}
export const withRedText = (Component) => {
return class WithRedComponent extends React.Component<{}, {}> {
public render(): JSX.Element {
return (
<div style={{color: "red"}}>
<Component {...this.props} />
</div>
);
}
};
};
export const HelloWorldComponentWithRedText = withRedText(HelloWorldComponent);
我从父调用这个文件JSX像这样:
public render(): JSX.Element {
return (
<div>
Test #1: <HelloWorldComponent/>
Test #2: <HelloWorldComponentWithRedText />
Test #3: { withRedText(<HelloWorldComponent />) }
</div>
)
}
第一和第二测试按预期工作---文字是在第二个红色。但第三行不会呈现任何内容。我预计第二和第三行是一样的。
当我使用调试器对其进行检查时,测试#2的参数是HelloWorldComponent
类型的组件,但测试#3看到Component = Object {$$typeof: Symbol(react.element), ...}
。
有没有一种方法可以从JSX/TSX文件中动态地包装一个类似{ withRedText(<HelloWorldComponent />) }
的语法的组件?
(打字稿2.1.4 &阵营15.4.0)
我不认为你可以直接/隐式地从JSX调用HOC。考虑到JSX的实现以及HOC如何工作,我认为它不会对性能有好处:每次组件重新呈现时,都会再次调用HOC函数,重新创建包装组件类,然后调用它。
你往往能获得类似的效果,不过,通过创建需要另一个组件作为参数的组件:
const WithRedText = ({component: Component, children, ...props}) => (
<div style={{color: "red"}}>
<Component {...props}>{children}</Component>
</div>
);
(我传递component
为小写,因为这似乎是惯例。道具,而是内WithRedText
,我大写它,因为这是JSX如何确定自定义组件,而不是HTML标签)
然后,要使用它:
ReactDOM.render(
<div className="container">
<WithRedText component={HelloWorldComponent} />
</div>,
);
好吧,这很有道理,谢谢。我最终想知道是否可以动态地叠加它们,例如'{withFeatureOne(withFeatureTwo(
想到你的答案后,我意识到我问的是错误的问题。我不能像我想的那样调用HOC,但我仍然可以使用'React.CreateComponent()'获得体面的语法。我可以用像'export const createComponent =(component,... args)=> React.createElement(component,args)这样的帮助函数清理它;'然后像这样从JSX调用它:'{createComponent(withRedText(HelloWorldComponent ))'。我可以尽可能多地链接它们,并且语法在眼睛上不太难。 – mikebridge
参见:http://codepen.io/mikebridge/pen/jyxjwe – mikebridge
这是因为在试验#3传递给它的实例:代替HelloWorldComponent
的类型/类别<HelloWorldComponent />
,。 JSX被转化为相当于大量对象实例化样板的东西。
这是JavaScript的版本:http://codepen.io/mikebridge/pen/mRLvRd – mikebridge