gpt4 book ai didi

React dependency injection or similar?(对依赖项注入或类似的反应?)

转载 作者:bug小助手 更新时间:2023-10-25 16:50:42 24 4
gpt4 key购买 nike



In Angular.js it is possible to use dependency injection. I did some browsing and was not able to find an implementation of it. Does React have something similar to that?

在Angular.js中,可以使用依赖注入。我浏览了一下,没有找到它的实现。React有类似的东西吗?


更多回答
优秀答案推荐

React has IoC, but not any concept of a DI container like Angular. That is, instead of having a container that knows how to create objects and passing in dependencies, you pass them explicitly by passing props to the component when you instantiate it (like <MyComponent items={this.state.items} />).

Reaction有IoC,但没有像Angular这样的DI容器的任何概念。也就是说,不是让容器知道如何创建对象并传递依赖项,而是在实例化组件时通过向组件传递道具来显式传递它们(如 )。



Passing dependencies as props isn't very common the React world though. Props are mostly used to pass data to components and not services/stores. But there's nothing stopping you from passing services/stores or even components as props (and certainly nothing wrong with it).

不过,将依赖项作为道具传递在Reaction世界中并不常见。道具主要用于将数据传递给组件,而不是服务/存储。但是,没有什么能阻止您将服务/商店甚至组件作为道具来传递(当然,这没有什么错)。



React has the concept of a context which is a shared object for a whole tree of components. So the top level component can say that the context for its subtree has an object containing something like a UserStore, a MessageStore, etc. A component further down in the component hierarchy can then say that it wants access to the UserStore in its context. By saying that, the UserStore is accessible to that component without having to explicitly pass it down from the top component to the bottom, and the component requesting it doesn't know how it was created/passed to it.

React有上下文的概念,它是整个组件树的共享对象。因此,顶层组件可以说其子树的上下文有一个包含UserStore、MessageStore等内容的对象。然后,组件层次结构中更低的组件可以说它希望访问其上下文中的UserStore。通过这样说,UserStore可以被该组件访问,而不必显式地将其从顶部组件传递到底部,并且请求它的组件不知道它是如何创建/传递给它的。



It has the benefit of a DI container where you have a central place for object creation which can be passed in further down. Here's a good intro to contexts: https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html

它具有DI容器的好处,在那里您有一个中心位置来创建对象,该对象可以进一步向下传递。这里有一个很好的上下文介绍:https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html



Contexts are still an undocumented feature of React, which means that its API can change in any coming versions of React, so you might want to use it sparsely until it becomes documented.

上下文仍然是Reaction的一个未记录在案的功能,这意味着它的API可能会在任何即将到来的Reaction版本中更改,所以您可能希望在它成为有记录的内容之前尽量少用它。



From react-in-patterns:

来自模式中的反应:




Most of the solutions for dependency injection in React components are based on context. I think that it's good to know what happens under the hood. As the time of this writing one of the most popular ways for building React apps involves Redux. The famous connect function and the Provider there use the context.




And from the react docs:

从Reaction文档中:




Context is an advanced and experimental feature. The API is likely to change in future releases.



Most applications will never need to use context. Especially if you are just getting started with React, you likely do not want to use context. Using context will make your code harder to understand because it makes the data flow less clear. It is similar to using global variables to pass state through your application.



If you have to use context, use it sparingly.



Regardless of whether you're building an application or a library, try to isolate your use of context to a small area and avoid using the context API directly when possible so that it's easier to upgrade when the API changes.




I have found a way to inject dependencies without using the context thanks to the usage of an IoC container.

由于使用了IoC容器,我找到了一种在不使用上下文的情况下注入依赖项的方法。



Most containers support two kinds of injections:

大多数容器支持两种注入:




  • Constructor injection: In order to use “constructor injection” the IoC container needs to be able to create the instances of the classes. In React the components sometimes are just functions (not classes) and we can’t delegate the creation of the instances of the components to the IoC container. This means that constructor injection powered by IoC containers don’t play nicely with React.

    构造函数注入:为了使用“构造函数注入”,IoC容器需要能够创建类的实例。在Reaction中,组件有时只是函数(而不是类),我们不能将组件实例的创建委托给IoC容器。这意味着由IoC容器驱动的构造函数注入不能很好地处理Reaction。


  • Property injection: Works nicely with React if what we want is to pass dependencies to components without passing them explicitly through each component.

    属性注入:如果我们想要的是将依赖项传递给组件,而不是显式地传递给每个组件,则可以很好地使用Reaction。




I use InversifyJS as IoC container and it property injection support to pass dependencies to components without passing them explicitly through each component and without using the context:

我使用InversifyJS作为IoC容器,它的属性注入支持将依赖项传递给组件,而不需要显式地传递每个组件,也不使用上下文:



import { pInject } from "./utils/di";
import { UserStore } from "./store/user";

class User extends React.Component<any, any> {

@pInject(UserStore)
private userStore: UserStore; // INJECTED!

public render() {
return (
<h1>{this.userStore.pageTitle}</h1>
);
}
}


The main advantage of using an IoC container like InversifyJS is that we are not using the context!

使用像InversifyJS这样的IOC容器的主要优势是我们不使用上下文!



You can learn more about it here.

你可以在这里了解更多关于它的信息。



I don't really like using contexts, since it's still an experimental feature of react and kind of bulky. I've also looked at DI frameworks like react-di but it required each component to be aware of the DI framework's way of injecting dependencies (i.e. knowing that the dependency is in the this.props.di object.).

我真的不喜欢使用情景,因为它仍然是反应的一个实验性特征,而且有点笨重。我还研究了像React-di这样的DI框架,但它要求每个组件都知道DI框架注入依赖项的方式(即知道依赖项在this.pros.di对象中)。



If we rule out contexts, the canonical way to inject something into a React component is through the use of props. The props are injected when you run React.createElement, i.e. for each jsx tag. The React.createElement function takes a component, some props and some children and returns a React element. I.e. (component, props, children) -> element.

如果我们排除了上下文,那么将一些东西注入Reaction组件的规范方法就是通过使用道具。当您运行React.createElement时,即为每个JSX标记注入道具。CreateElement函数接受一个组件、一些道具和一些子元素,并返回一个Reaction元素。即(组件、道具、子元素)->元素。



I made a createComponent function with almost the same signature as React.createElement but which returns a component instead, i.e. (component, props, children) -> component. Here it is:

我制作了一个createComponent函数,其签名与React.createElement几乎相同,但它返回一个组件,即(Component,Props,Child)->Component。它是这样的:



const createComponent = (type, defaultProps = {}, defaultChildren = null) => {
return ({ children, ...props }) => {
return React.createElement(
type,
{ ...defaultProps, ...props },
children || defaultChildren
);
};
};


The returned component can be injected in a prop, like in this example:

返回的组件可以注入道具中,如下例所示:



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} />;
}


Fiddle: https://jsfiddle.net/8971g8s5/3/

小提琴:https://jsfiddle.net/8971g8s5/3/



The good thing about this is that PropTypes will still work very well, so each component can clearly declare what kind of properties it wants.

这样做的好处是,PropTypes仍然可以很好地工作,因此每个组件都可以清楚地声明它想要什么类型的属性。



Also, the receiving end of the injection doesn't need to depend on any special implementation, just the normal props system of React. So the components needn't know that you're using dependency injection or how you do it, they just care about what props they receive.

此外,注入的接收端不需要依赖任何特殊的实现,只需要Reaction的正常道具系统。因此,组件不需要知道您正在使用依赖项注入或如何使用依赖项注入,它们只关心它们收到了什么道具。



I think you are looking for an agnostic dependency container to use in React.

我认为您正在寻找一个不可知的依赖项容器来在Reaction中使用。


Here you have 3:

这里有3个:



  1. InversifySugar: InversifyJS framework to handle hierarchichal dependency systems (like Angular or Nest).

  2. InversifyJS: a lighweight container with a complete API to manage dependencies.

  3. Tsyringe: a lightweight container developed by Microsoft. Very similar to InversifyJS.


Choose one of these and look for examples of how to integrate it in React, GitHub is plenty of this kind of samples.

选择其中之一,并寻找如何将其集成到Reaction中的示例,GitHub就是大量此类示例。


更多回答

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com