React is a library for creating front end views. It has a big ecosystem of libraries that work with it. Also, we can use it to enhance existing apps.
To store data in a central place for easy accessibility by components, we have to use some state management solutions. React-Redux is a popular choice.
In this article, we’ll look at how to add it to our React app and simple use cases.
Installation
To install the react-redux
package, we have install react-redux
and its dependency redux
.
We can install both by running:
npm install react-redux redux
with NPM or if we use Yarn:
yarn add react-redux redux
Set Up a Redux Store
After installing both packages, we have to set up our Redux store to hold our data.
To do this we write:
import { createStore } from "redux";
function counterReducer(state = 0, action) {
switch (action.type) {
case "INCREMENT":
return state + 1;
default:
return state;
}
}
const store = createStore(counterReducer);
The code above creates a Redux store by creating the counterReducer
reducer function.
The reducer specifies how the app’s state changes in response to actions sent to the store.
Our counterReducer
only accepts one action, which is 'INCREMENT'
. We respond to the action by returning the state
and adding 1 to it.
There’s also a default case to just return the state
value as is.
Then we create a store by calling Redux’s createStore
function and passing in our reducer.
It returns the store
, which we can pass into our React app.
Connecting the Store to our React App
This is where we need the functions of React-Redux.
We can connect the store to our app so we can store our app’s state in the store by using React-Redux’s connect
function.
connect
takes 2 functions, which are mapStateToProps
and mapDispatchToProps
. They’re the first and second argument respectively.
First, we can put the whole app together by connecting our store with the React app as follows:
import React from "react";
import { Provider, connect } from "react-redux";
import { createStore } from "redux";
import ReactDOM from "react-dom";
function counterReducer(state = 0, action) {
switch (action.type) {
case "INCREMENT":
return state + 1;
default:
return state;
}
}
const store = createStore(counterReducer);
class App extends React.Component {
onClick() {
this.props.increment();
}
render() {
const { count } = this.props;
return (
<>
<button onClick={this.onClick.bind(this)}>Increment</button>
<p>{count}</p>
</>
);
}
}
const mapDispatchToProps = dispatch => {
return {
increment: () => dispatch({ type: "INCREMENT" })
};
};
const mapStateToProps = state => ({
count: state
});
App = connect(
mapStateToProps,
mapDispatchToProps
)(App);
const rootElement = document.getElementById("root");
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
rootElement
);
In the code, we have an app that shows a number going up as we click the Increment button.
The first step to connect the store to our React app is to wrap the Provider
component around our whole app.
To do this we, wrote the following:
<Provider store={store}>
<App />
</Provider>
Then we define the mapStateToProps
and mapDispatchToProps
functions as follows:
const mapDispatchToProps = dispatch => {
return {
increment: () => dispatch({ type: "INCREMENT" })
};
};
const mapStateToProps = state => ({
count: state
});
In mapStateToProps
we return a object to map the state
object to a React component prop name as indicated in the property name. The state
is the state stored in the Redux store.
So we mapped state
to the prop count
.
In mapDispatchToProps
, we get the dispatch
parameter, which is a function used to dispatch our action to the store, and return an object with the name for the function we can access from the props to call and dispatch the action.
So in mapDispatchToProps
, increment
is our function name. We can call it by running this.props.increment
in our App
component.
increment
is a function that runs dispatch({ type: “INCREMENT” })
.
Then in our App
component, we define the onClick
method to call this.props.increment
to dispatch the ‘INCREMENT’
action to our counterReducer
via our Redux store and increase the state
by 1.
Then since we have mapStateToProps
, the latest value is being observed by App
and the latest value is available via this.state.count
as indicated in mapStateToProps
.
Then when we click the Increment button, we’ll get the number going up by 1.
This will happen with every click.
Conclusion
We can use Redux in our React app by creating a store.
Next, we use the React-Redux Provider
component and wrap it around our App
entry-point component. We pass our Redux store to the store
prop so that we can map the state and dispatch actions to props.
Then connecting it to our store via React Redux’s connect
function. We pass in the mapStateToProps
and mapDispatchToProps
to map the store’s state to our component’s props and map our dispatch function call to our props respectively.