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,storeitself 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 incomponentWillReceivePropsof theconnect()ed component.Specify
contextTypesforstoreand accesscontextdirectlyIf you really want to grab
storefromcontextyourself (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.contextif you don’t specifycontextTypes. My free Egghead lesson on implementing<Provider>withcontextcovers that.@awestroke was correct, I just needed to correctly specify
contextTypesin 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().