Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 如何在React(TypeScript)中使用依赖注入组件_Reactjs_Typescript - Fatal编程技术网

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

Reactjs 如何在React(TypeScript)中使用依赖注入组件,reactjs,typescript,Reactjs,Typescript,我目前正在将React集成到基于TypeScript的框架中。不幸的是,只要我想注入组件,输入就不再正确了 我知道这不是很多人使用React的方式,但是我们不想使用高阶组件,而是希望使用依赖注入,因为我们认为这是更好的模式 我试着做了以下几点 import * as React from "react"; import * as ReactDOM from "react-dom"; export class Foo extends React.Component { public re

我目前正在将React集成到基于TypeScript的框架中。不幸的是,只要我想注入组件,输入就不再正确了

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

我试着做了以下几点

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(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>'.
如果我这样试的话

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

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(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>'.
src/app/test.tsx(15,33)中的错误:错误TS2345:类型为“Foo”的参数不能分配给类型为“string | statelementcomponent | ComponentClass”的参数。
类型“Foo”不可分配给类型“ComponentClass”。
类型“Foo”与签名“new(props:{},context?:any):Component”不匹配。
我不太赞成在这个场景中使用
作为任何
,因为我希望能够重构
Foo
,而不必手动检查每个实例是否正确传递了道具


我从React.sfc收到了消息,但据我所知,它并没有解决我面临的问题。

组件的名称具有误导性,因为它应该是一个构造函数,而构造函数通常都有pascal大小写名称。应该相应地键入它,因为
component:Foo
意味着它是
Foo
的一个实例

可能应该是:

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

    public render(): void {
        ReactDOM.render(
            <this.Component />
            document.querySelector("#root")
        );
    }
}
导出类Foobar{
构造函数(私有组件:typeof Foo){}
公共呈现():void{
ReactDOM.render(
document.querySelector(“根”)
);
}
}
React已经使用依赖项注入模式。可以使用道具和上下文API注入依赖项,例如:

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

@银色翅膀的男孩给出了正确的答案。我想这感觉有点错误,但我完全理解原因(JSX等)。

问题是,您已经声明,您的构造函数使用了
Foo
的一个实例,由类型
Foo
表示,但实际上您是在使用
Foo
表示的
typeoffoo
类进行传递

更具体地说,是变化

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


顺便说一下,高阶组件是一种依赖注入模式。依赖注入只不过是参数化。

因为您不是从
Foo
创建对象,而是传递类本身,似乎
ComponentClass
将是您想要使用的类型我们想要使用依赖项注入,因为在我们看来这是更好的模式-您可能从错误的角度来处理它。React已经通过道具和上下文使用依赖项注入模式。哦,是的,我想这是有道理的,依赖项注入程序可以解决这个问题:)@estus上下文不是真正的依赖项注入,它的容器感知模式。这只有在ReactDOM.render中使用JSX时才是正确的,我在第二个示例中没有使用大写字母,在第一个示例中使用大写字母。不遵循此约定可能会导致错误,
component
name并不表示要获取构造函数作为参数。开发人员看到
component:Foo
会想,'好吧,component是Foo的一个实例,有意义',而它本身就是Foo。是的,我同意这种类型,这就是我问的原因。但是这种情况下的大写字母是没有意义的。对于习惯了这种约定的开发人员来说,这是有意义的,因为
私有组件:Foo
错误可以一眼看出,而
私有组件:Foo
乍一看似乎还可以。