Created
April 14, 2017 07:18
-
-
Save Nitive/6c9cdd50e286c1ed52aa8bd6f6d028fb to your computer and use it in GitHub Desktop.
Dependency injection for React
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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