DEV Community

Cover image for Redux Toolkit React Counter App
Ravi Sharma
Ravi Sharma

Posted on

Redux Toolkit React Counter App

Hi, I'm Ravi. I'm an JavaScript Developer by profession and a Youtuber also, subscribe my channel JavaScript Centric If you are one of the lover of JavaScript.

In this post I will share the basic example of a Counter App implemented using react and redux toolkit.

Why use Redux Toolkit? 🤷‍♂️

Redux toolkit includes all the functions or "tools", you want for a Redux application. At the end of the day, less code and faster setups of Redux in every scenario.

Here's what the Official docs said :

These tools should be beneficial to all Redux users. Whether you're a brand new Redux user setting up your first project, or an experienced user who wants to simplify an existing application, Redux Toolkit can help you make your Redux code better.

Create a react app

Create-react-app gives you a basic React app so don't have to setup React yourself.

npx create-react-app readuxtoolkit_app
Enter fullscreen mode Exit fullscreen mode

Now we need to add react-redux and Redux Toolkit to this app:

npm install --save react-redux @reduxjs/toolkit
Enter fullscreen mode Exit fullscreen mode

You can install react-bootstrap also:

npm install --save react-bootstrap
Enter fullscreen mode Exit fullscreen mode

Folder Structure

We will be following this folder structure. Create two folders app and features inside src folder. Inside app folder create file store.js and inside features folder create two other folders coin and counter.

Basic React , Redux Toolkit Directory Structure

Steps To Follow

  1. Create a Redux Store
  2. Provide the Redux Store to React Main App.js
  3. Create a Redux State Slice
  4. Add Slice Reducers to the Store
  5. Use Redux State and Actions in React Component
  6. To use redux state in other component use useSelector hook from react-redux

1.First Step is to configure our Store, now this is where you'll see the magic of redux toolkit! Now your redux store src/app/store.js will contains

import { configureStore } from '@reduxjs/toolkit';

export const store = configureStore({
  reducer: {

  },
})
Enter fullscreen mode Exit fullscreen mode

Here configureStore({}) wraps createStore to provide simplified configuration options and good defaults. It can automatically combine your slice reducers, adds whatever Redux middleware you supply, includes redux-thunk by default, and enables use of the Redux DevTools Extension.

2.Now we need to connect our store to our app or just wrap it with Redux. Import store.js and Provider from react-redux into src/index.js

import { store } from "./app/store";
import { Provider } from "react-redux";

ReactDOM.render(
    <React.StrictMode>
        <Provider store={store}>
            <App />
        </Provider>
    </React.StrictMode>,
    document.getElementById("root")
);
Enter fullscreen mode Exit fullscreen mode

Now start your application with npm start and open up Redux DevTools, you should see @@INIT. Congrats you have setup Redux with React!! 🥳️

3.Third Step is to create a counterSlice.js file inside features/counter folder.

import { createSlice } from '@reduxjs/toolkit'

const initialStateValues = {
  coin: 0,
}

export const counterSlice = createSlice({
  name: 'counter',
  initialState: initialStateValues,
  reducers: {
    increment: (state) => {
      state.coin += 1
    },
    decrement: (state) => {
      state.coin -= 1
    },
    incrementByAmount: (state, action) => {
      state.coin += action.payload
    },
    decrementByAmount: (state, action) => {
      state.coin -=action.payload
    }
  },
})

// Action creators are generated for each case reducer function
export const { increment, decrement, incrementByAmount, decrementByAmount } = counterSlice.actions

export default counterSlice.reducer
Enter fullscreen mode Exit fullscreen mode

Basically createSlice accepts an object of reducer functions, a slice name( in our case slice name is 'counter') and an initialState(here initialStateValues that contains coin) and automatically generates a slice reducer with corresponding action creators and action types.

4.Fourth Step is to Add Slice Reducers to the Store. So update store.js will look like below:

import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './../features/counter/counterSlice';

export const store = configureStore({
  reducer: {
      counter: counterReducer
  },
})
Enter fullscreen mode Exit fullscreen mode

In case if you are using other reduces than you have to use combineReducers from redux as below:

import { configureStore } from "@reduxjs/toolkit";
import counterReducer1 from "./../features/counter/counterSlice1";
import counterReducer2 from "./../features/counter/counterSlice2";

import { combineReducers } from "redux";

const reducer = combineReducers({
  // put all your reducers here!
  counterReducer1,
  counterReducer2,
});

export const store = configureStore({
  reducer,
});

Enter fullscreen mode Exit fullscreen mode

5.To use actions in other component we have to use useDispatch() provided by "react-redux" and used to dispatch our actions like

const dispatch = useDispatch();
now call dispatch action by passing action name inside it.
In features/counter/Counter.js we are using different actions like (increment, decrement, incrementByAmount, decrementByAmount).

import { useDispatch } from "react-redux";
import {
  increment,
  decrement,
  incrementByAmount,
  decrementByAmount,
} from "./counterSlice";
import Button from 'react-bootstrap/Button';
import 'bootstrap/dist/css/bootstrap.min.css';

const Counter = () => {
  const dispatch = useDispatch();
  return (
    <div>
      <hr />
      <Button
        aria-label="Increment value"
        onClick={() => {
          dispatch(increment());
        }}
        variant="success"
        className="mx-2"
      >
        Increase
      </Button>

      <Button
        className="button"
        aria-label="Decrement value"
        onClick={() => {
          dispatch(decrement());
        }}
        variant="danger"
        className="mx-2"
      >
        Decrease
      </Button>

      <Button
        className="button"
        aria-label="Decrement value"
        onClick={() => {
          dispatch(incrementByAmount(10));
        }}
        variant="success"
        className="mx-2"
      >
        IncrementBy 10
      </Button>

      <Button
        className="button"
        aria-label="Decrement value"
        onClick={() => {
          dispatch(decrementByAmount(10));
        }}
        variant="danger"
        className="mx-2"
      >
        DecrementBy 10
      </Button>
    </div>
  );
};
export default Counter;
Enter fullscreen mode Exit fullscreen mode

6.To use redux state in other component use useSelector hook from react-redux like in features/coin/Coin.js.

Remember the name of our reducer we imported in counterSlice.js, that's the name we have to use when using the useSelector() hook.

It receives our state in arguments and then we can extract every other variable in our state with the help of destructuring like below.

import {useSelector} from 'react-redux';
const Coin = () => {
  const {coin} = useSelector((state)=>state.counter);
  return (
    <div style={{paddingTop: '200px'}}>
      <b><big className="value">Coins: {coin}</big></b>
    </div>
  );
};

export default Coin;
Enter fullscreen mode Exit fullscreen mode

Now in your Terminal, to start your React app:

npm start
Enter fullscreen mode Exit fullscreen mode

Congrats you made it! 🥳️

You have setup React and Redux Toolkit! There are obviously many complex use cases of Redux which I will cover in the upcoming post.

Subscribe to my youtube channel: JavaScript Centric

Like ❤️ and Share 🙏🏻 if you found this post helpful.

Top comments (0)