如何在React(TypeScript)中使用依赖注入的组件

时间:2018-10-25 12:54:38

标签: reactjs typescript

我目前正在将React集成到基于TypeScript的框架中。不幸的是,当我要注入组件时,类型不再正确。

我知道这不是很多人使用React的方式,但是我们希望使用依赖注入,而不是使用更高阶的组件,因为我们认为这是更好的模式。

我尝试执行以下操作

.main-navigation ul li a:hover{color:red;}

但是不幸的是,这并不起作用。输出以下错误

import * as React from "react";
import * as ReactDOM from "react-dom";

export class Foo extends React.Component {
    public render() {
        return (<div>Bar</div>);
    }
}

export class Foobar {
    constructor(private component: Foo) {}

    public render(): void {
        const Component = this.component;

        ReactDOM.render(
            <Component />, // <Foo /> works perfectly
            document.querySelector("#root")
        );
    }
}

如果我这样尝试

ERROR in src/app/test.tsx(17,14): error TS2604: JSX element type 'Component' does not have any construct or call signatures.

结果如下

public render(): void {
    ReactDOM.render(
        React.createElement(this.component, {}),
        document.querySelector("#root")
    );
}

在这种情况下,我真的不赞成使用ERROR in src/app/test.tsx(15,33): error TS2345: Argument of type 'Foo' is not assignable to parameter of type 'string | StatelessComponent<{}> | ComponentClass<{}, any>'. Type 'Foo' is not assignable to type 'ComponentClass<{}, any>'. Type 'Foo' provides no match for the signature 'new (props: {}, context?: any): Component<{}, any, any>'. ,因为我希望能够重构as any,而不必手动检查每个实例是否正确传递了道具。

我听说过React.sfc,但据我所知,它不能解决我面临的问题。

3 个答案:

答案 0 :(得分:1)

component名称具有误导性,因为它应该是构造函数,并且构造函数通常具有pascal大小写名称。应该相应地键入它,因为component: Foo表示它是Foo的实例。

可能应该是:

export class Foobar {
    constructor(private Component: typeof Foo) {}

    public render(): void {
        ReactDOM.render(
            <this.Component />
            document.querySelector("#root")
        );
    }
}

反应已使用依赖项注入模式。依赖关系可以通过props和上下文API注入,例如:

ReactDOM.render(<App Foo={FooImplementation}/>, ...);

答案 1 :(得分:0)

@有银翼的男孩给出了正确的答案。我想感觉有点不对,但是我完全理解为什么(JSX之类的。)

答案 2 :(得分:0)

问题是您已经声明构造函数使用Foo实例,由类型Foo表示,但是实际上您正在使用表示为{{1}的类Foo进行传递}。

更具体地说,更改

typeof Foo

收件人

export class Foobar {
  constructor(public component: Foo) {}
}

顺便说一句,高阶分量是依赖注入模式。依赖注入无非就是参数化。