我可以直接从React中的JSX / TSX中调用HOC吗?

时间:2017-02-03 22:39:23

标签: javascript reactjs typescript jsx tsx

我在TypeScript中有一个React HOC,但是当我在TSX Component 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); 方法中调用它时它似乎不起作用。这是一个例子:

public render(): JSX.Element {
    return (
       <div>
           Test #1: <HelloWorldComponent/>
           Test #2: <HelloWorldComponentWithRedText />
           Test #3: { withRedText(<HelloWorldComponent />) }
       </div>
    )
}

我从这样的父JSX文件中调用它:

HelloWorldComponent

第一次和第二次测试按预期工作---第二次测试中的文本为红色。但第三行没有任何表现。我预计第二和第三行是相同的。

当我使用调试器逐步执行它时,测试#2的参数是Component = Object {$$typeof: Symbol(react.element), ...}类型的组件,但测试#3看到的是{ withRedText(<HelloWorldComponent />) }

有没有办法用JSX / TSX文件中的{{1}}语法动态包装一个Component?

(TypeScript 2.1.4&amp; React 15.4.0)

Here it is on CodePen

2 个答案:

答案 0 :(得分:1)

这是因为在测试#3中,您传递了一个实例:<HelloWorldComponent />,而不是类型/类HelloWorldComponent。 JSX被转化为大量的对象实例化样板。

答案 1 :(得分:1)

我认为您不能直接/隐式地从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>,
);

请参阅http://codepen.io/joshkel/pen/MJGLOQ