Skip to content

Instantly share code, notes, and snippets.

@JSila
Created March 4, 2018 13:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JSila/a54c10012f23b4e7a1f4bc6aae120ca6 to your computer and use it in GitHub Desktop.
Save JSila/a54c10012f23b4e7a1f4bc6aae120ca6 to your computer and use it in GitHub Desktop.
Helpers for providing and consuming multiple react contexts
import React, {Component} from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import createContext from 'create-react-context'
const Theme = createContext("light")
const Language = createContext("en")
const Whatever = createContext("whatever")
const Consume = ({contexts, children}) => {
const values = []
const _consume = ctxs => {
const [First, ...rest] = ctxs
return (
<First.Consumer>
{value => {
values.push(value)
return rest.length ? _consume(rest) : children(...values)
}}
</First.Consumer>
)
}
return _consume(contexts)
}
const Provide = ({contexts, children}) => {
return contexts.reduce((res, [Context, value]) => {
return React.createElement(Context.Provider, {
children: res,
value
})
}, children);
}
class Root extends Component {
constructor(props) {
super(props)
this.state = {
language: 'sl',
theme: 'dark'
}
this.toggleTheme = this.toggleTheme.bind(this)
this.toggleLanguage = this.toggleLanguage.bind(this)
}
toggleLanguage() {
return this.setState(state => ({
language: state.language === "en" ? "sl": "en"
}))
}
toggleTheme() {
return this.setState(state => ({
theme: state.theme === "light" ? "dark": "light"
}))
}
render() {
const contexts = [
[Theme, this.state.theme],
[Language, this.state.language]
]
return (
<Provide contexts={contexts}>
<Consume contexts={[Theme, Language, Whatever]}>
{(theme, language, whatever) => (
<App theme={theme} language={language} whatever={whatever} />
)}
</Consume>
<button onClick={this.toggleTheme}>Toggle theme</button>
<button onClick={this.toggleLanguage}>Toggle language</button>
</Provide>
)
}
}
ReactDOM.render(<Root/>, document.getElementById('root'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment