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

Can I call HOC directly from within JSX / TSX in React?

我在 TypeScript 中有一个 React HOC,但当我从 TSX 组件 render 方法中调用它时它似乎不起作用。这是一个例子:

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 />) } 之类的语法动态包装组件?

(TypeScript 2.1.4 & React 15.4.0)

Here it is on CodePen

那是因为在测试#3 中,您传递了一个实例:<HelloWorldComponent />,而不是 type/class HelloWorldComponent。 JSX 被转译为大量对象实例化样板文件。

我不认为您可以从 JSX 直接/隐式调用 HOC。考虑到 JSX 的实现以及 HOC 的工作原理,我认为这对性能没有好处:每次组件 re-renders,它都会再次调用 HOC 函数,re-creates 包装的组件 class,然后调用它。

不过,您通常可以通过创建一个将另一个组件作为参数的组件来获得类似的效果:

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