React-Redux

Salot Jay
Bitontree
Published in
4 min readDec 31, 2020

--

React-Redux is the official React binding for Redux. It lets your React components read data from a Redux store, and dispatch actions to the store to update data.

Installation

To use React-Redux with your React app:

npm install react-redux

Why Use React Redux?

Redux itself is a standalone library that can be used with any UI layer or framework, including React, Angular, Vue, Ember, and vanilla JS. Although Redux and React are commonly used together, they are independent of each other.

If you are using Redux with any kind of UI framework, you will normally use a “UI binding” library to tie Redux together with your UI framework, rather than directly interacting with the store from your UI code.

React Redux is the official Redux UI binding library for React. If you are using Redux and React together, you should also use React-Redux to bind these two libraries.

Connecting the Components

React-Redux provides a connect function for you to read values from the Redux store (and re-read the values when the store updates).

The connect function takes two arguments, both optional:

  • mapStateToProps: This is called every time the store state changes. It receives the entire store state and should return an object of data this component needs.
  • mapDispatchToProps: This parameter can either be a function, or an object.
  • If it’s a function, it will be called once on component creation. It will receive dispatch as an argument, and should return an object full of functions that use dispatch to dispatch actions.
  • If it’s an object full of action creators, each action creator will be turned into a prop function that automatically dispatches its action when called. Note: We recommend using this “object shorthand” form.
const mapStateToProps = (state, ownProps) => ({
// … computed data from state and optionally ownProps
})
const mapDispatchToProps = {
// … normally is an object full of action creators
}
// `connect` returns a new function that accepts the component to wrap:const connectToStore = connect(mapStateToProps,mapDispatchToProps)
// and that function returns the connected, wrapper component:
const ConnectedComponent = connectToStore(Component)// We normally do both in one step, like this:connect(mapStateToProps,mapDispatchToProps)(Component)

Accessing the Store

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 and state are propagated to connected components, or access the store directly. Here are some examples of how to do this.

Using the 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.

Providing Custom Context,

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:

// You can pass the context as an option to connectexport default connect(mapState,mapDispatch,null,{ context: MyContext })(MyComponent)// or, call connect as normal to start
const ConnectedComponent = connect(mapState,mapDispatch)(MyComponent)
// Later, pass the custom context as a prop to the connected component
<ConnectedComponent context={MyContext} />

Multiple Stores

Redux was designed to use a single store. However, if you are in an unavoidable position of needing to use multiple stores, with v6 you may do so by providing (multiple) custom contexts. This also provides natural isolation of the stores as they live in separate context instances.

// a naive exampleconst ContextA = React.createContext();const ContextB = React.createContext();// assuming reducerA and reducerB are proper reducer functionsconst storeA = createStore(reducerA);const storeB = createStore(reducerB);
// supply the context instances to Provider
function App() {
return (
<Provider store={storeA} context={ContextA} />
<Provider store={storeB} context={ContextB}>
<RootModule />
</Provider>
</Provider>
);}
// fetch the corresponding store with connected components// you need to use the correct context
connect(mapStateA, null, null, { context: ContextA })(MyComponentA)
// You may also pass the alternate context instance directly to the connected component instead<ConnectedMyComponentA context={ContextA} />// it is possible to chain
connect()
// in this case MyComponent will receive merged props from both storescompose(connect(mapStateA, null, null, { context: ContextA }),
connect(mapStateB, null, null, { context: ContextB }))(MyComponent);

--

--