React Redux provides APIs that allow your components to dispatch actions and subscribe to data updates from the store.
As part of that, React Redux abstracts away the details of which store you are using, and the exact details of how that store interaction is handled. In typical usage, your own components should never need to care about those details, and won't ever reference the store directly. React Redux also internally handles the details of how the store and state are propagated to connected components, so that this works as expected by default.
However, there may be certain use cases where you may need to customize how the store is passed to connected components, or access the store directly. Here are some examples of how to do this.
Understanding Context UsageInternally, React Redux uses React's "context" feature to make the Redux store accessible to deeply nested connected components. As of React Redux version 6, this is normally handled by a single default context object instance generated by React.createContext()
, called ReactReduxContext
.
React Redux's <Provider>
component uses <ReactReduxContext.Provider>
to put the Redux store and internal subscription wrappers into context. useSelector
, useDispatch
, and connect
call useContext(ReactReduxContext)
to read those values and handle updates.
useStore
Hook
The useStore
hook returns the current store instance from the default ReactReduxContext
. If you truly need to access the store, this is the recommended approach.
Instead of using the default context instance from React Redux, you may supply your own custom context instance.
<Provider context={MyContext} store={store}>
<App />
</Provider>
If you supply a custom context, React Redux will use that context instance instead of the one it creates and exports by default.
After you’ve supplied the custom context to <Provider />
, you will need to supply this context instance to all of your connected components that are expected to connect to the same store:
export default connect(
mapState,
mapDispatch,
null,
{ context: MyContext }
)(MyComponent)
const ConnectedComponent = connect(
mapState,
mapDispatch
)(MyComponent)
<ConnectedComponent context={MyContext} />
The following runtime error occurs when React Redux does not find a store in the context it is looking. For example:
<Provider />
, but did not provide the same instance (or did not provide any) to your connected components.<Provider />
.Custom Context and the hooks APIInvariant Violation
Could not find "store" in the context of "Connect(MyComponent)". Either wrap the root component in a
<Provider>
, or pass a custom React context provider to<Provider>
and the corresponding React context consumer to Connect(Todo) in connect options.
To access the custom context via the hooks API, you can create custom hooks via the hook creator functions.
Multiple StoresRedux was designed to use a single store. However, if you are in an unavoidable position of needing to use multiple stores, as of v6 you may do so by providing (multiple) custom contexts. This also provides a natural isolation of the stores as they live in separate context instances.
const ContextA = React.createContext(null);
const ContextB = React.createContext(null);
const storeA = createStore(reducerA);
const storeB = createStore(reducerB);
function App() {
return (
<Provider store={storeA} context={ContextA} />
<Provider store={storeB} context={ContextB}>
<RootModule />
</Provider>
</Provider>
);
}
connect(mapStateA, null, null, { context: ContextA })(MyComponentA)
<ConnectedMyComponentA context={ContextA} />
compose(
connect(mapStateA, null, null, { context: ContextA }),
connect(mapStateB, null, null, { context: ContextB })
)(MyComponent);
Using ReactReduxContext
Directly
In rare cases, you may need to access the Redux store directly in your own components. This can be done by rendering the appropriate context consumer yourself, and accessing the store
field out of the context value.
caution
This is not considered part of the React Redux public API, and may break without notice. We do recognize that the community has use cases where this is necessary, and will try to make it possible for users to build additional functionality on top of React Redux, but our specific use of context is considered an implementation detail. If you have additional use cases that are not sufficiently covered by the current APIs, please file an issue to discuss possible API improvements.
import { ReactReduxContext } from 'react-redux'
function MyConnectedComponent() {
const { store } = useContext(ReactReduxContext)
}
Further Resources
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4