Skip to content

Instantly share code, notes, and snippets.

@Nitive
Created April 14, 2017 07:18
Show Gist options
  • Save Nitive/6c9cdd50e286c1ed52aa8bd6f6d028fb to your computer and use it in GitHub Desktop.
Save Nitive/6c9cdd50e286c1ed52aa8bd6f6d028fb to your computer and use it in GitHub Desktop.
Dependency injection for React
import * as pick from 'lodash/pick';
import * as React from 'react';
import { MobileWebsiteApi } from '../api/api';
import { FixedComponentsStore } from '../components/fixed/store';
import { CookiesUtils } from '../utils/cookies';
// экспортируем типы контекста, чтобы было удобней импортировать
// import { connect, MobileWebsiteApi } from '../../utils/context_provider';
export { MobileWebsiteApi, FixedComponentsStore, CookiesUtils };
export interface IAppContext {
api: MobileWebsiteApi;
fixedComponentsStore: FixedComponentsStore;
cookiesUtils: CookiesUtils;
}
export interface IContextProviderProps {
context: IAppContext;
}
const contextTypes = {
appContext: React.PropTypes.object.isRequired,
};
export class ContextProvider extends React.Component<IContextProviderProps, void> {
public static childContextTypes = contextTypes;
public getChildContext() {
return { appContext: this.props.context };
}
public render() {
return React.Children.only(this.props.children as React.ReactNode);
}
}
// Usage:
// In root component
// ```tsx
// <ContextProvider context={props.context}>
// <App />
// </ContextProvider>
// ```
// In any component:
// ```tsx
// const connectedComponent = di(['api'])(Component);
// ```
export function di<K extends keyof IAppContext>(keys: K[]) {
return function wrap<OwnProps>(
Component: React.ComponentClass<Pick<IAppContext, K> & OwnProps>,
): React.ComponentClass<OwnProps> {
return class ConnectedToAppContextComponent extends React.Component<OwnProps, void> {
public static displayName = `connectContext(${Component.displayName || Component.name})`;
public static contextTypes = contextTypes;
private pickedContext: Pick<IAppContext, K>;
public constructor(props: OwnProps, context: { appContext: IAppContext }) {
super(props, context);
this.pickedContext = pick<Pick<IAppContext, K>, IAppContext>(context.appContext, keys);
}
public render() {
return <Component {...this.pickedContext} {...this.props} />;
}
};
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment