Skip to content

Instantly share code, notes, and snippets.

@jimbolla
Last active September 10, 2016 14:54
Show Gist options
  • Save jimbolla/495076a92fb02fd65a46f1dbd9d0be3f to your computer and use it in GitHub Desktop.
Save jimbolla/495076a92fb02fd65a46f1dbd9d0be3f to your computer and use it in GitHub Desktop.
withStore
import hoistStatics from 'hoist-non-react-statics'
import invariant from 'invariant'
import { Component, PropTypes, createElement } from 'react'
export default function withStore(
{
getDisplayName = name => `WithStore(${name})`,
methodName = 'withStore',
storeKey = 'store',
withRef = false,
} = {}
) {
const contextTypes = {
[storeKey]: PropTypes.object.isRequired,
}
return function wrapWithWithStore(WrappedComponent) {
invariant(
typeof WrappedComponent == 'function',
`You must pass a component to the function returned by ` +
`connect. Instead received ${WrappedComponent}`
)
const wrappedComponentName = WrappedComponent.displayName
|| WrappedComponent.name
|| 'Component'
const displayName = getDisplayName(wrappedComponentName)
class WithStore extends Component {
constructor(props, context) {
super(props, context)
this.setWrappedInstance = this.setWrappedInstance.bind(this)
invariant(this.getStore(),
`Could not find "${storeKey}" in either the context of "${displayName}". ` +
`Wrap the root component in a <Provider>.`
)
}
getStore() {
return this.context[storeKey]
}
getWrappedInstance() {
invariant(withRef,
`To access the wrapped instance, you need to specify ` +
`{ withRef: true } in the options argument of the ${methodName}() call.`
)
return this.wrappedInstance
}
setWrappedInstance(ref) {
this.wrappedInstance = ref
}
render() {
const withExtras = {
...this.props,
[storeKey]: this.getStore()
}
if (withRef) withExtras.ref = this.setWrappedInstance
return createElement(WrappedComponent, withExtras)
}
}
WithStore.WrappedComponent = WrappedComponent
WithStore.displayName = displayName
WithStore.contextTypes = contextTypes
return hoistStatics(WithStore, WrappedComponent)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment