Skip to content

Instantly share code, notes, and snippets.

@sheharyarn
Last active August 12, 2021 14:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sheharyarn/23e220d0575f16c3b2b28e3204b13622 to your computer and use it in GitHub Desktop.
Save sheharyarn/23e220d0575f16c3b2b28e3204b13622 to your computer and use it in GitHub Desktop.
Custom Wrapper around React Contexts
/**
* Custom Implementation of React Context to manage
* global application state
*
* @author Sheharyar Naseer (@sheharyarn)
* @license MIT
*
* Normal Usage:
*
* ```
* <AppContext.Consumer>
* { (context, setContext) => (/* do something */) }
* </AppContext.Consumer>
* ```
*
* HOC Usage:
*
* ```
* export default AppContext.withConsumer(MyComponent);
* ```
*
* Links:
* - https://reactjs.org/docs/context.html
* - https://auth0.com/blog/react-context-api-managing-state-with-ease/
* - https://medium.freecodecamp.org/reacts-new-context-api-how-to-toggle-between-local-and-global-state-c6ace81443d0
*/
import React from 'react'
// TODO:
// Have a separate SessionContext ?
const Context = React.createContext({});
const initialContext = {
env: process.env.NODE_ENV,
session: {
signedIn: false,
user: null,
token: null,
}
};
// Custom Provider
class Provider extends React.Component {
constructor(props) {
super(props);
this.state = {
context: initialContext,
setContext: this.handleSetContext.bind(this),
};
}
handleSetContext(context) {
const newContext = Object.assign(this.state.context, context);
this.setState(newContext);
}
render() {
const {env} = this.state.context;
if (env === 'development')
console.log("Global Context:", this.state.context);
return (
<Context.Provider value={this.state}>
{this.props.children}
</Context.Provider>
);
}
}
// Custom Consumer
class Consumer extends React.Component {
render() {
const {children} = this.props;
return (
<Context.Consumer>
{ ({context, setContext}) => children(context, setContext) }
</Context.Consumer>
);
}
}
// ContextualComponent HOC
const withConsumer = (Component) => {
return function ContextualComponent(props) {
return (
<Context.Consumer>
{ (consumer) => <Component {...props} consumer={consumer} /> }
</Context.Consumer>
);
};
}
// Export Methods
export default {Provider, Consumer, withConsumer};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment