react-redux: Can't get store from context
My top level component is like so:
ReactDOM.render(
<div>
<Provider store={store}>
<App />
</Provider>
</div>,
document.getElementById('app')
);
And my App component is like so:
@connect(state => state)
export default class App extends React.Component {
render() {
return (
<div className={cx('container')}>
<Workspace />
<Blotter />
</div>
);
}
}
I’m not using React Router, and I’ve ensured that there is only one React instance loaded.
If I break at the top of App.render
, this.context
has no store on it. However, this._reactInternalInstance._context
does have the store attached. Obviously I can grab this, but I’m guessing I shouldn’t really use that one.
Why is there no store on this.context
? I want to subscribe to certain state changes.
Thanks.
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Comments: 22 (5 by maintainers)
There are two possible approaches here.
Use
connect()
and don’t worry about the contextThis is the approach we suggest. Use
connect()
, let it subscribe to the store, and don’t worry about the React context API. There are limitations: indeed,store
itself is not passed down as a prop, but subscribing to it inside aconnect()
ed component is an anti-pattern anyway. Letconnect()
take care of subscriptions. If you want to cause a side effect when store state changes, do this incomponentWillReceiveProps
of theconnect()
ed component.Specify
contextTypes
forstore
and accesscontext
directlyIf you really want to grab
store
fromcontext
yourself (my advice: don’t do this unless you have a very good reason!) you need to specifycontextTypes
. Context is opt-in in React, and you won’t receivethis.context
if you don’t specifycontextTypes
. My free Egghead lesson on implementing<Provider>
withcontext
covers that.@awestroke was correct, I just needed to correctly specify
contextTypes
in my component, and the store was then added as expected:You are not supposed to access this.context.store anyway. You use connect to pick the part of the state you want.
React only populates the context if you specify contextTypes in your component. You will however notice that the props in your <App /> component is populated from the store, as you specified in your mapStateToProps function.
If your want to subscribe to state changes, make sure you set contextTypes. Or, even better, handle the subscriptions on the root level (where you create the store). However, I can’t help but think you really don’t need to subscribe to changes, as the react tree is re-rendered each time the state changes anyway.
Use the prop-types package.
@Damnum
connect(..., ..., ..., { shouldHandleStateChanges: false })
@gaearon Is there any better way to use store.subscribe other than getting store from context (‘connect’ doesn’t help)? I’m new to Redux but I feel it’s quite weird when I try to follow http://redux.js.org/docs/api/Store.html doc to do subscribe but don’t know how to get the store object. Searched a long time on the internet and finally get here. I feel there should be a more apparent place to let people know the normal way to get store for store.subscribe().