首页 文章

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

提问于
浏览
2

我在TypeScript中有一个React HOC,但是当我在TSX Component 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 />) } 语法动态包装Component?

(TypeScript 2.1.4和React 15.4.0)

Here it is on CodePen

2 回答

  • 1

    我不认为您可以直接/隐式地从JSX调用HOC . 考虑到JSX的实现以及HOC的工作方式,我认为它不会对性能有好处:每次组件重新渲染时,它再次调用HOC函数,重新创建包装的组件类,然后调用它 .

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

    const WithRedText = ({component: Component, children, ...props}) => (
        <div style={{color: "red"}}>
          <Component {...props}>{children}</Component>
        </div>
    );
    

    (我将 component 作为小写传递,因为这似乎是道具的惯例,但是在_992747中,我大写它,因为这就是JSX识别自定义组件而不是HTML标签的方式 . )

    然后,使用它:

    ReactDOM.render(
        <div className="container">
            <WithRedText component={HelloWorldComponent} />
        </div>,
    );
    

    http://codepen.io/joshkel/pen/MJGLOQ .

  • 1

    那是因为在测试#3中你传递了一个实例: <HelloWorldComponent /> ,而不是类型/类 HelloWorldComponent . JSX被转化为相当于很多对象实例化样板的内容 .

相关问题