Patrón arquitectónico de inyección de dependencia en una aplicación React

Transcripción del informe de Sergei Nesterov de la conferencia FrontendLive 2020 .





! , . , , , , , React . Dependency Injection IoC-. : , .





- . , , - -.





Dependency Injection React-. , , . , Dependency Injection , . 





:





Frontend + DI ≠ ♥







- , Dependency Injection, , , , . Dependency Injection -, , , . , , , , .





, Dependency Injection. , Angular Nest.js ( NodeJS). Angular Dependency Injection , React- React .





— : 





Frontend + DI = ♥



 





, React- Dependency Injection. , .





. React MobX. - , React- . , . 





, , , . , , , , , . , , . :





: , , . , 30 . , , , - . , — , . 





, , — . .





. : . , , , , . , , . 





. React 16.2 16.3. , API, . - , ( ), — props hell. 





- , , , . - , , . , . , . 





, Dependency Injection. — - , SOLID.





SOLID





  • .





  • /.





  • .





  • .





  • .





— . ?





  • . .





  • . .





, , : 





: ( Juicer) ( Apple). Juicer Apple. ? , : Juicer Apple. :





  • Apple. 





  • . Juicer, , Apple.





  • . «» «», , , . «».





, , IFruit , «» , - . 





Apple — — , . :





Juicer, -, , - IFruit. Apple Juicer. , .





, ! , , - , . 





, , . 





Dependency Injection. , : 





  • Constructor injection.





  • Property Injection.





  • Setter Injection.





Constructor injection. , . , : , - . , , :





Property Injection. . property . , , -, — , , : 





-, , . -, , , - . - IoC-, , .





Setter Injection. , Property Injection, property , , . . . , Property Injection, ( ), :





:

  • Constructor Injection — . , .





  • Property Injection — .





  • Setter Injection — . Inversion of Control-.





IoC-, . 





. IoC- — , , , : , , , , .





. IoC- — , — . , , . 





React

react-simple-di, react-ioc, typescript-ioc, inversifyJS.





inversifyJS, . React. , Dependency Injection Angular, inversifyJS.





devtools. , — . , - , inversifyJS , :





. Juicer, Apple. inversifyJS, , injectable-, .





inject- Apple, . — inversifyJS, , .





: « , , !» , . :





? Apple IFruit. @inject Apple.





? IFruit is not defined — ReferenceError. 





? , , runtime TypeScript — JavaScript . , , InversifyJS , .





, ? , — :





, FruitKey. — , Apple . , Dependency Injection .





Reflect-metadata

Reflect-metadata — , ( ) . , :





Juicer, — injectable- inject-. , - inversify- , Juicer . , reflect-metadata Juice.





console.log(Reflect.getMetadataKeys) . :





  • design:paramtypes;





  • inversify:tagged;





  • inversify:paramtypes.





, , inversifyJS , . inversify:tagged:





console.log(Reflect.getMetadata) inversify:tagged , Juicer , FruitKey. inversifyJS : , . 





Dependency Injection+React

— Dependency Injection React-. , React , React . , . , , . , . .





import React from 'react';
import { interfaces } from 'inversify';
 
const context = React.createContext<interfaces.Container | null>(null);
 
export default context;
      
      



. , , React. : , React.createContext null. inversifyJS , .





, ? DiProvider — -, . , : (children) React-, :





type Props = {
   container: interfaces.Container;
   children: ReactNode;
};
 
export function DiProvider({ container, children }: Props) {
   return <Context.Provider value={container}>{children}</Context.Provider>;
}
      
      



High-Order-, . High-Order-, , , withProvider, — , :





export function withProvider<P, C>(
   component: JSXElementConstructor<P> & C,
   container: interfaces.Container
) {
 
   class ProviderWrap extends Component<Props> {
       public static contextType = Context;
       public static displayName = `diProvider(${getDisplayName(component)})`;
 
       public constructor(props: Props, context?: interfaces.Container) {
           super(props);
 
           this.context = context;
 
           if (this.context) {
               container.parent = this.context;
           }
       }
 
       public render() {
           const WrappedComponent = component;
 
           return (
               <DiProvider container={container}>
                   <WrappedComponent {...(this.props as any)} />
               </DiProvider>
           );
       }
   }
 
   return ProviderWrap as ComponentClass<Props>;
}
      
      



. Typescript, , High-Order- , . , DiProvider , .





, DI-. , parent- . , , .





, . High-Order-, , . , , — Dependence-.





Dependence- , . . , inversify, binding ( ), tagged binding — . 





, , , TypeScript , . , , . 





inject. , DI-, resolve, . , . 





, , High-Order- React, . 





Next.js, . Next.js : npm install, npm run dev — . pages- HOC withProvider , .





, HOC diInject, , - . 





: ListModel , inSingletonScope, , get- . Props , booksListModel , . inversifyJS React- , , .





, Dependency Injection, — , inversifyJS.





, :





SPA- . React Router . , : fetch-, - fetch — , . 





, , , . , 1, 2.





, , . , .





, — , , -, , -, js, . 





:





, . : CommentService, CommentModel .





, inversifyJS Container Module, , . , . , .





inversifyJS, . — tagged bindings. ? , :





, . inversifyJS tagged , FruitKey ( ) . — , FruitKey — , , — , — . , whenTargetTagged.





, , — named bindings:





, , , — Store, . , , JuicerKey c AppleJuicer. named inversifyJS. 





whenAnyAncestorNamed , AppleJuicer, — OrangeJuicer. 





, Juicer FruitKey , , , — . Store .





Dependency Injection+React

DI React? , , — , . , , , runtime JavaScript, :





, , Store StoreKey. Store , , , TypeScript , - .





- - , , .





container.bind<Store>("StoreKey").to(Store);
      
      



, . 





 

, . Dependency Injection, . . .





. : — playground , inversifyJS NodeJS, — React-. High-Order- React inversifyJS.








All Articles