Last active
July 27, 2019 15:17
-
-
Save nielsboecker/a0e59ccab8449796bc566809ce019139 to your computer and use it in GitHub Desktop.
TypeScript HOC (Higher-Order Component) for wrapping React components with context consumers
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
// Usage in other components | |
import { PropsWithContext, withAppContext } from "./WithAppContext"; | |
export interface ISomeComponentProps extends PropsWithContext { | |
otherProp: string; | |
} | |
class SomeComponent extends Component<ISomeComponentProps> { | |
// or: can also extend Component<PropsWithContext> or extend Component<SomeProps & PropsWithContext> | |
render() { | |
console.log(this.props.context); | |
// ... | |
} | |
export default withAppContext(SomeComponent); |
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
// Definition of HOC, could be placed in same file where you createContext() | |
export type ComponentPropsWithContext = { context?: IAppState }; | |
/** | |
* @deprecated This caused problems for components that access props.children | |
*/ | |
export function withAppContextOld< | |
OutProps extends ComponentPropsWithContext, | |
InProps = Omit<OutProps, "context"> | |
>(Component: ComponentType<InProps>) { | |
return (props: InProps) => ( | |
<AppContext.Consumer> | |
{(context: IAppState) => <Component {...props} context={context} />} | |
</AppContext.Consumer> | |
); | |
} | |
/** | |
* Higher-order component to wrap an arbitrary component and provide it with app context. | |
* | |
* @param InnerComponent the component to wrap | |
* @param pureComponent whether to return a PureComponent (use false if InnerComponent uses other | |
* props and fails to update properly due to PureComponent's flat diffs) | |
*/ | |
export const withAppContext = <ComponentProps extends {}>( | |
InnerComponent: ComponentType<ComponentProps>, | |
pureComponent: boolean = true | |
) => { | |
const componentType = pureComponent ? PureComponent : Component; | |
return class WithContext extends componentType<ComponentProps & PropsWithContext> { | |
render() { | |
return ( | |
<AppContext.Consumer> | |
{(context: IAppState) => <InnerComponent {...this.props} context={context} />} | |
</AppContext.Consumer> | |
); | |
} | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment