Skip to content

Instantly share code, notes, and snippets.

@ryanflorence
Last active October 27, 2018 15:37
Show Gist options
  • Star 29 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save ryanflorence/1e1290571337ebcea1c5a748e8f5b37d to your computer and use it in GitHub Desktop.
Save ryanflorence/1e1290571337ebcea1c5a748e8f5b37d to your computer and use it in GitHub Desktop.
import React from 'react'
const provideContext = (contextKey, contextType) => (
React.createClass({
childContextTypes: {
[contextKey]: contextType
},
getChildContext() {
const { children, ...props } = this.props
return {
[contextKey]: props
}
},
render() {
return React.Children.only(this.props.children)
}
})
)
export default provideContext
import React from 'react'
export default (contextKey, contextType) => (
(Component) => (
React.createClass({
contextTypes: {
[contextKey]: contextType
},
render() {
const props = {
...this.props,
[contextKey]: this.context[contextKey]
}
return <Component {...props}/>
}
})
)
)
// usage
const Something = withContext('router', PropTypes.object)(React.createClass({
render() {
this.props.router
}
}))
@ryanflorence
Copy link
Author

Usage

// PropTypes.js
export const app = shape({ user: object, token: string })

// AppContext.js
import provideContext from './provideContext'
import { app } from './PropTypes'
export default provideContext('app', app)

// SomeComponent.js
import React from 'react'
import withContext from './withContext'
import { app } from '../PropTypes'
export default withContext('app', app)(React.createClass({
  render() {
    this.props.app
    // ...
  }
}))

// entry.js
// AppContext props become context
render(<AppContext user={__USER__} token={__TOKEN__}><SomeComponent/></AppContext>

This way components can only provide one context (no naming collisions, just shadowing) and a component can only ask for on context, and the entire context API is wrapped so the entire app is easily protected from future changes.

@kentcdodds
Copy link

thumbs-bm3TCIXwXfIGI

@robcolburn
Copy link

There's a typo in SomeComponent.js right? It should be importing from AppContext?

@ryanflorence
Copy link
Author

nope.

@appsforartists
Copy link

👏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment