在Angular.js中,可以使用依赖注入。我做了一些浏览,但没有找到它的实现。React有类似的东西吗?
发布于 2015-05-19 13:46:40
React有IoC,但没有像Angular这样的DI容器的概念。也就是说,不是让容器知道如何创建对象并传递依赖项,而是通过在实例化组件(如<MyComponent items={this.state.items} />
)时将道具传递给组件来显式传递它们。
不过,在React世界中,将依赖项作为道具传递并不常见。Props主要用于将数据传递给组件,而不是服务/存储。但是没有什么能阻止你传递服务/商店,甚至组件作为道具(当然也没有什么问题)。
React具有context
的概念,它是整个组件树的共享对象。因此,顶层组件可以说它的子树的上下文有一个对象,其中包含UserStore、MessageStore等内容。然后,组件层次结构中更低的组件可以说它想要访问上下文中的UserStore。也就是说,该组件可以访问UserStore,而不必从顶部组件显式地向下传递它,并且请求它的组件不知道它是如何创建的/传递给它的。
它有DI容器的好处,在那里你有一个创建对象的中心位置,可以进一步向下传递。下面是对上下文的一个很好的介绍:https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html
上下文仍然是React的一个未文档化的特性,这意味着它的API可以在任何即将到来的React版本中更改,所以您可能希望在它成为文档化之前尽量少用它。
发布于 2016-06-24 18:02:12
我真的不喜欢使用contexts,因为它仍然是react的实验特性,而且有点笨重。我还研究过像react-di
这样的依赖注入框架,但它要求每个组件都知道依赖注入依赖的方式(即知道依赖存在于this.props.di
对象中)。
如果我们排除了上下文,那么将一些东西注入React组件的规范方法就是通过使用道具。这些道具是在你运行React.createElement
时注入的,也就是每个jsx标签。React.createElement
函数接受一个组件、一些道具和一些子元素,并返回一个React element。即(component, props, children) -> element
。
我创建了一个与React.createElement
签名几乎相同的createComponent
函数,但它返回的是一个组件,即(component, props, children) -> component
。这就是它:
const createComponent = (type, defaultProps = {}, defaultChildren = null) => {
return ({ children, ...props }) => {
return React.createElement(
type,
{ ...defaultProps, ...props },
children || defaultChildren
);
};
};
返回的组件可以注入到道具中,如下例所示:
const Banner = ({ children, TextComponent }) => {
return <div className="banner">
<TextComponent>{children}</TextComponent>
</div>;
}
const SayHelloComponent = ({ ParagraphComponent }) => {
return <ParagraphComponent>Hello world!</ParagraphComponent>;
}
const ParentComponent = () => {
const inject = {
ParagraphComponent: createComponent(Banner, {
TextComponent: createComponent('span', {
className: "my-pretty-class",
}),
}),
}
return <SayHelloComponent {...inject} />;
}
小提琴:https://jsfiddle.net/8971g8s5/3/
这样做的好处是PropTypes
仍然可以很好地工作,所以每个组件都可以清楚地声明它想要什么类型的属性。
此外,注入的接收端不需要依赖于任何特殊的实现,只需要React的正常道具系统。所以组件不需要知道你正在使用依赖注入或者你是如何做的,他们只关心他们收到了什么道具。
https://stackoverflow.com/questions/30311081
复制相似问题