Skip to content

Instantly share code, notes, and snippets.

@kasper573
Last active March 9, 2018 09:18
Show Gist options
  • Save kasper573/043758103358d22bb321a7f9f1208ec8 to your computer and use it in GitHub Desktop.
Save kasper573/043758103358d22bb321a7f9f1208ec8 to your computer and use it in GitHub Desktop.
import * as React from 'react';
import * as PropTypes from 'prop-types';
let contextCounter = 0;
/**
* Temporary polyfill for React 16.3 createContext
*/
export function createContext<ContextProps> (defaultValues: ContextProps = {} as ContextProps) {
contextCounter += 1;
const contextKey = '__context__' + contextCounter + '__';
const contextTypes = {[contextKey]: PropTypes.any};
class ContextProvider extends React.Component<{values?: Partial<ContextProps>}> {
static childContextTypes = contextTypes;
getChildContext () {
return {[contextKey]: this};
}
render () {
return this.props.children;
}
}
class ContextConsumer extends React.Component<{
children: (contextProps: ContextProps) => React.ReactNode
}> {
static contextTypes = contextTypes;
context: any;
render () {
const provider: ContextProvider = this.context[contextKey];
const mergedValues = Object.assign({}, defaultValues, provider.props.values);
return this.props.children(mergedValues);
}
}
const connect = <T extends React.ComponentClass>(DecoratedComponent: T): T => {
return class ContextConnection extends React.Component {
render () {
const {children, ...localProps} = this.props;
return (
<ContextConsumer>
{(contextProps) => (
<DecoratedComponent {...contextProps} {...localProps}>
{children}
</DecoratedComponent>
)}
</ContextConsumer>
);
}
} as T;
};
return {
connect,
Provider: ContextProvider,
Consumer: ContextConsumer
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment