Reactjs 如何在React(TypeScript)中使用依赖注入组件
我目前正在将React集成到基于TypeScript的框架中。不幸的是,只要我想注入组件,输入就不再正确了 我知道这不是很多人使用React的方式,但是我们不想使用高阶组件,而是希望使用依赖注入,因为我们认为这是更好的模式 我试着做了以下几点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
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
乍一看似乎还可以。