Register to get access to free programming courses with interactive exercises

Connecting Redux Toolkit to React React: Redux Toolkit

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

To integrate it, we need two packages, the Toolkit itself and react-redux.

# Run 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);
// Wrapping the application in a Provider
// and passing the repository into it
  <Provider store={store}>
    <App />

We initialize the repository using the configureStore() function, which, unlike the same function in Redux, knows how to combine redusers independently. The function takes as input an object with the reducerkey, 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: {
    // counter is the name inside the state.counter object
    counter: counterReducer,

The reducers themselves are in the slices directory. Toolkit introduces a new concept,Slice which combines Reducers, Actions and more. We'll talk more about slices in the next lesson.

// 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;
    // example with data
    incrementByAmount: (state, action) => {
      state.value += action.payload;

// Slice generates actions that are exported 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. The useDispatch() function is used 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 means the whole state
  const count = useSelector((state) => state.counter.value);
  // 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.

Part of this initialization is done once and then hardly ever changes. The main application code will be added in components and slices. And unlike pure Redux, there will be much less of this code, thanks to the slices and the ability to mutate the data within the reduces. More on this 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

From a novice to a developer. Get a job or your money back!

Frontend Developer icon
Development of front-end components for web applications
start anytime 10 months

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.