We recommend using React's new context API for dependency injection, because it is perfect for passing information through to any arbitrary child within your app.
However, it needs a little work for it to play nicely with higher-order components.
Setting up React Context
Consider the following example, using vanilla React context:
import { createContext } from 'react'
export default createContext()
import { Provider } from 'redux'
import { withEffects } from 'refract-rxjs'
import RefractContext from './refractContext'
import configureStore from './configureStore'
import App from './components/App'
const store = configureStore()
ReactDOM.render(
<Provider store={store}>
<RefractContext.Provider value={{ store }}>
<App />
</RefractContext.Provider>
</Provider>,
document.getElementById('root')
)
import MyComponent from './MyComponent' // includes effects, but no context
import RefractContext from './refractContext'
const MyView = props => (
<RefractContext.Consumer>
{dependencies => <MyComponent {...dependencies} {...props} />}
</RefractContext.Consumer>
)
This code successfully puts dependencies into context and pulls them out again where needed, but it's not a particularly nice pattern. It's a pain to have to import the context and the component separately, and manually pass the dependencies through.
Thankfully, there's a solution for this!
Using Context With react-zap
At first glance, it might seem obvious to do this:
import MyComponent from './MyComponent' // includes effects AND context
const MyView = props => <MyComponent {...props} />
Which is definitely a lot nicer!
But we can do better - instead of importing and connecting our Refract context every time we use withEffects, we can enhance the default withEffects HoC by wrapping it with our context once in a sideEffects.js file: