Hi, I just updated to 6.0.0 and have a question. I can't really figure out from the docs how to access the store from context anymore.
My app is wrapped with
<Provider store={store}>
Then in any component I could access it with
MyComponent.contextTypes = {
store: PropTypes.object.isRequired
};
->
this.context.store
How do i achieve the same thing with 6.0.0?
We use the new context API, which is exported as ReactReduxContext.
Got it working but this also seem to subscribe to updates from the store.
What I want is just access to the store that I created without subscribing to updates.
I can of course export it from where I created it. Is that the best way?
What are you actually trying to accomplish?
I want to read a value from the store in componentWillUnmount.
So I want access to the store without subscribing to any updates.
Previously I got access with this.context.store.getState()
Per the React docs on using context, you would either need to add a contextType field to your component so that you can access the context value as this.context, or have a wrapper component that renders a <Context.Consumer>, extracts the store, and passes it as a prop to your own component.
What kind of value are you needing to read from the store on unmount? Why not just connect the component, and extract that value in mapState as normal?
I'm just trying to think as performant as possible. Hence not wanting to subscribe if I don't need all the updates.
contextType is a React thing, not a React-Redux thing, and should work fine.
As I asked, what kind of value are you trying to use? Is it something that you expect will be changing frequently? Do you have specific reasons why you think connecting to get this value will be a performance issue? Why do you only need this in componentWillUnmount?
My general reaction here is that you're over-thinking the performance implications, but I can't say for sure because I don't know the specifics of your app and what you're trying to do.
Ok. I used contextType before upgrading to 6.0.0. When I upgraded it stopped working... The release notes said this:
"Any library that attempts to access the store instance out of legacy context will break, because we now put the store state into a
The value I want to read is a string that does change quite a lot and in this component I only need it when it unmounts. It's used for statistics tracking in this case.
Maybe I'm overthinking but I always try to minimize the number of renders in my components. And since I got my case working as I wanted before I want it to work the same way now when upgrading.
Note that contextTypes and contextType are not the same thing.
React defines legacy context using syntax like:
class MyComponent extends React.Component {}
MyComponent.contextTypes = {
a : PropTypes.string,
b : PropTypes.object
}
When the new context API was released, it originally could only be used via a render-props API:
<MyContext.Consumer>
{ (contextValue) => {
// do stuff with the context value here
});
</MyContext.Consumer>
To help with the migration from old context to new context, the React team added a new way to access new context in 16.6 called contextType:
class MyClass extends React.Component {
static contextType = MyContext;
componentDidMount() {
let value = this.context;
/* perform a side-effect at mount using the value of MyContext */
}
}
So, you should be able to do:
```js
class MyComponent extends React.Component {
static contextType = ReactReduxContext;
componentWillUnmount() {
const storeState = this.context.store.getState();
// do something with the store state here
}
}
Ahh, didn't know about that way :) Will try it first thing tomorrow.
Thanks!
contextType seem to work the same way as Context.Consumer in this case. meaning I get updates.
this.context now includes both store and storeState. is there a way to only get store?
No, the React-Redux <Provider> puts both of those into the context.
If you want that, you can just make your own context:
// StoreContext.js
import React from 'react'
export const StoreContext = React.createContext()
export default StoreContext
// app.js
import StoreContext from './StoreContext'
const store = createStore(reducer)
ReactDOM.render(
<Provider store={store}>
<StoreContext.Provider value={store}>
<App />
</StoreContext.Provider>
</Provider>,
root
)
The new API is really simple 馃憤
You can use ReactReduxContext from 'react-redux' :
Docs and example here : https://react-redux.js.org/api/provider
Most helpful comment
Note that
contextTypesandcontextTypeare not the same thing.React defines legacy context using syntax like:
When the new context API was released, it originally could only be used via a render-props API:
To help with the migration from old context to new context, the React team added a new way to access new context in 16.6 called
contextType:So, you should be able to do:
```js
class MyComponent extends React.Component {
static contextType = ReactReduxContext;
}