How To Build A Redux-Powered React App
How To Build A Redux-Powered React App
Let's get everything we need setup for our project. Just follow these steps and you'll
be up and running in no time.
cd react-app-with-redux
npm start
How to Build the Main App
5. How to create the Reducer
To create a reducer, �rst create a folder inside src named actionTypes . Then
create a �le inside it named actionTypes.js . This �le will contain all the actions the
application will be dealing with.
Since our app will have the functionality of adding and deleting items, we need the
above two action types.
Next create a folder inside the src called reducers and create a new �le in it
named cartReducer.js . This �le will contain all the reducer logic related to the
cart component.
const initialState = {
numOfItems: 0,
};
case DELETE_ITEM:
return {
...state,
numOfItems: state.numOfItems - 1,
};
default:
return state;
}
};
If none of the action types matche, then the state is returned as it is.
Finally we make a default export of the cakeReducer function to use it in the store
creation process.
Now it's time to provide this store to the App component. For this we'll use the
<Provider> tag that we get from the react-redux library.
We wrap the whole App component inside the <Provider> tag using the following
syntax:
// rest of the code ...
<Provider store={store}>
<div>App Component</div>
// child components of App/ other logic
</Provider>
By wrapping the App component inside the <Provider> tag, all the children
component of App will get access of the store . You can read my previous article on
What is Redux? Store, Actions, and Reducers Explained for Beginners to know
more.
import "./App.css";
import { Provider } from "react-redux";
import store from "./store";
function App() {
return (
<Provider store={store}>
<div>App Component</div>
</Provider>
);
}
In the above code we created two action creators (pure JS functions that returns
action object) called addItem() and deleteItem() . Both the action creators
return action objects with a speci�c type .
Note: Each action object must have a unique type value. Along with it, any
additional data passed with the action object is optional and will depend on the
logic used for updating the state
Create a component folder inside src and a Cart.js �le inside it. Add the
following lines inside Cart.js :
import "./App.css";
import { Provider } from "react-redux";
import store from "./store";
import Cart from "./component/Cart";
function App() {
return (
<Provider store={store}>
<Cart />
</Provider>
);
}
Just to make it a bit presentable, I have added a bit of basic styling in App.css as
follows:
button {
margin: 10px;
font-size: 16px;
letter-spacing: 2px;
font-weight: 400;
color: #fff;
padding: 23px 50px;
text-align: center;
display: inline-block;
text-decoration: none;
border: 0px;
cursor: pointer;
}
.green {
background-color: rgb(6, 172, 0);
}
.red {
background-color: rgb(221, 52, 66);
}
.red:disabled {
background-color: rgb(193, 191, 191);
cursor: not-allowed;
}
.cart {
text-align: center;
}
Import the hook from react-redux and use the following syntax to read the store
with useSelector hook:
After adding the useSelector hook, your Cart.js �le will look something like this:
Console logging the state will give us the initial state that we set in the reducer �le
in step 5.
10. How to dispatch an action on button click with
the useDispatch hook
The react-redux library gives us another hook called the useDispatch hook. It helps
us dispatch the actions or action creators which in turn return actions. The syntax is
as follows:
Thus adding a dispatcher into our Cart.js will �nally make the �le look something
like this:
Note how on click of the Add Item to Cart button, we dispatch the action creator
addItem() that we created in step no. 7.
Similarly on click on the Remove Item from Cart button, we dispatch the action
creator with deleteItem() .
The state variable stores the state of the app, which is basically an object with a
key numOfItems . So state.numOfItems gives us the current number of items value
in the store.
We display this information in the view in the line <h2>Number of items in Cart:
{state.numOfItems}</h2> .
To dig a bit deeper, when a user clicks the Add Item to Cart button, it dispatches the
addItem() action creator. This, in turn, returns an action object with type type:
ADD_ITEM .
As shown in step 5, the reducer takes the state and the action as input, switches on
the action type and returns the fresh new instance of the updated state.
In this example, when the action with type: ADD_ITEM matches the �rst switch
case, it �rst makes a copy of the entire state using the spread operator ...state .
Then it makes the necessary update – which in the case of adding items is
numOfItems: state.numOfItems + 1 (that is increasing the numOfItems by 1).
Similarly, using the same logic, on clicking on the Remove Item from Cart button, an
action with type type: DELETE_ITEM is dispatched which goes and decreases the
numOfItems by 1.
Notice how we were able to control the behavior of the Remove Item from Cart
button based on the value of numOfItems in the Redux store. As a negative number
of items does not makes sense, we disabled the Remove Item from Cart button if
state.numOfItems <= 0 .
This way we are able to prevent the user from decreasing the number of items in
the cart if its already 0.
This was a basic example to show you how we can control the behavior of various
DOM elements based on the internal state of the app.
And there you go! We just �nished setting up our �rst Redux-powered React
application. Now you can go ahead and create various other components based on
your requirements and share a common global state among them.