Register to get access to free programming courses with interactive exercises

Connecting Redux Toolkit to React React: Redux Toolkit

In this lesson, we'll build a simple application with two buttons that change the counter value. It will allow you to see the basic concepts of the Redux Toolkit.

Let us try to integrate it. We need two packages — react-redux and the toolkit itself:

# Run it at the root of the project
npm install @reduxjs/toolkit react-redux

Before we start putting the puzzle together, let's look at the directory structure that we'll start from. This structure is the simplest, but not the only possible one:

  | App.jsx
  | index.js
  | counterSlice.js

Let's start at the top level. Here we need the <Provider> component, which contains the repository and sneaks it deep into the component tree via the context:

// file: index.jsx

import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';

import App from './components/App.jsx';
import store from './slices/index.js';

const mountNode = document.getElementById('container');
const root = ReactDOM.createRoot(mountNode);
// We wrap the application in the `Provider` and pass the repository into it
  <Provider store={store}>
    <App />

We initialize the repository using the configureStore() function. It knows how to combine reducers independently, unlike in Redux. As input, it takes an object with the reducer key, the value of which is an object with reducers:

// file: slices/index.js

import { configureStore } from '@reduxjs/toolkit';
import counterReducer from '../slices/counterSlice.js';

export default configureStore({
  reducer: {
    // The `counter` is the name inside the `state.counter` object
    counter: counterReducer,

The reducers themselves are in the slices directory. Toolkit introduces a new concept — a slice which combines Reducers, Actions, and more. We'll talk more about it in the next lesson, but now we will see the code example:

// file: slices/counterSlice.js

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

// Initial value
const initialState = {
  value: 0,

const counterSlice = createSlice({
  name: 'counter',
  // Reducers in slices mutate the state and return nothing to the outside
  reducers: {
    increment: (state) => {
      state.value += 1;
    decrement: (state) => {
      state.value -= 1;
    // An example with some data
    incrementByAmount: (state, action) => {
      state.value += action.payload;

// The slice generates actions that export separately
// Actions are generated automatically from reducer key names
export const { increment, decrement, incrementByAmount } = counterSlice.actions;

// By default, the reducer generated by the slice is exported
export default counterSlice.reducer;

Now the most important thing, let's look at the Toolkit in action. Here we rely on hooks. As before, to change the state in the repository, we must pass an action to the dispatch() function. We use the useDispatch() function to get the dispatch:

// file: components/App.jsx

import React from 'react';
// The hooks are in `react-redux`
import { useSelector, useDispatch } from 'react-redux';
// Importing the desired actions
import { decrement, increment } from '../slices/counterSlice.js';

export default () => {
  // Pulling data from the `store.state` (meaning the whole state)
  const count = useSelector((state) => state.counter.value);
  // The code returns the `store.dispatch()` method of the current store
  const dispatch = useDispatch();

  return (
          aria-label="Increment value"
          onClick={() => dispatch(increment())}
          aria-label="Decrement value"
          onClick={() => dispatch(decrement())}
          Take away

And here's a real-life example:

See the Pen js_redux_toolkit_integration-1 by Hexlet (@hexlet) on CodePen.

You do some of this initialization once and then seldom change it because you will add the majority of application code in components and slides. Unlike pure Redux, there will be much less of this code, thanks to slices and the ability to mutate data within reducers. More on this we are going to discuss in the next lesson.

Do it yourself

  1. Create a repository to experiment with the code from the lesson
  2. Repeat the steps from the lesson locally inside this repository
  3. Commit changes to the repository

Recommended materials

  1. Redux DevTools

Hexlet Experts

Are there any more questions? Ask them in the Discussion section.

The Hexlet support team or other students will answer you.

About Hexlet learning process

For full access to the course you need a professional subscription.

A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.

Get access
hours of theory

Sign up

Programming courses for beginners and experienced developers. Start training for free

  • 130 courses, 2000+ hours of theory
  • 1000 practical tasks in a browser
  • 360 000 students
By sending this form, you agree to our Personal Policy and Service Conditions

Our graduates work in companies:

<span class="translation_missing" title="translation missing:">Bookmate</span>
<span class="translation_missing" title="translation missing:">Healthsamurai</span>
<span class="translation_missing" title="translation missing:">Dualboot</span>
<span class="translation_missing" title="translation missing:">Abbyy</span>
Suggested learning programs
Development of front-end components for web applications
10 months
from scratch
Start at any time

Use Hexlet to the fullest extent!

  • Ask questions about the lesson
  • Test your knowledge in quizzes
  • Practice in your browser
  • Track your progress

Sign up or sign in

By sending this form, you agree to our Personal Policy and Service Conditions
Toto Image

Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.