Skip to content

Instantly share code, notes, and snippets.

@kasper573
Last active September 2, 2018 16:41
Show Gist options
  • Save kasper573/853aa0660caee8a8e3f783d063d40512 to your computer and use it in GitHub Desktop.
Save kasper573/853aa0660caee8a8e3f783d063d40512 to your computer and use it in GitHub Desktop.
import * as React from 'react';
const hoistNonReactStatic = require('hoist-non-react-statics');
/**
* Decorator to form a HOC that acts like a react context consumer.
* Useful when you want context to be made available in an entire component and not just in render.
*
* Example:
* type MyContextProps = {foo: string};
* const MyContext = createContext<MyContextProps>({foo: 'bar'});
*
* @consume(MyContext.Consumer)
* class MyComponent extends React.Component<MyContextProps> {
* componentDidMount () {
* // Context is now available in the entire component
* console.log(this.props.foo);
* }
*
* render () {
* return <span>{this.props.foo}</span>;
* }
* }
*/
export function consume<ContextProps> (Consumer: React.Consumer<ContextProps>) {
return function decorateConsume<T extends React.ComponentClass> (DecoratedComponent: T): T {
class DecoratedConsumer extends React.Component {
render () {
const {children, ...localProps} = this.props;
return (
<Consumer>
{(contextProps) => (
<DecoratedComponent {...contextProps} {...localProps}>
{children}
</DecoratedComponent>
)}
</Consumer>
);
}
}
(DecoratedConsumer as any).displayName = `@consume(${DecoratedComponent.displayName || DecoratedComponent.name})`;
hoistNonReactStatic(DecoratedConsumer, DecoratedComponent);
return DecoratedConsumer as T;
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment