2

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

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>
    )
}

第一个和第二个测试按预期工作——第二个测试中的文本是红色的。但是第三行什么也不渲染。我预计第二行和第三行是相同的。

当我使用调试器单步执行它时,Test #2 的参数是 type 的 Component HelloWorldComponent,但 Test #3 看到的是Component = Object {$$typeof: Symbol(react.element), ...}.

有没有办法使用{ withRedText(<HelloWorldComponent />) }JSX/TSX 文件中的语法动态包装组件?

(TypeScript 2.1.4 & React 15.4.0)

这是在 CodePen 上

4

2 回答 2

1

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

于 2017-02-03T22:55:01.610 回答
1

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

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

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

(我component以小写形式传递,因为这似乎是 props 的约定,但在 内WithRedText,我将其大写,因为 JSX 识别自定义组件而不是 HTML 标记的方式。)

然后,使用它:

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

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

于 2017-02-03T22:58:31.497 回答