How to use Redux Toolkit with React Native?

Share this Content

As React Native developers, we know that efficient state management is key to building robust and scalable mobile applications. In a previous blog, we explored how to use Redux for state management in React Native. Now, let’s take it up a notch and introduce you to Redux Toolkit, a more refined and developer-friendly approach to working with Redux.

Before we dive into the practical steps of using Redux Toolkit, let’s take a moment to understand why Redux Toolkit has gained popularity over traditional Redux. Here’s a simple comparison:

AspectReduxRedux Toolkit
BoilerplateInvolves writing extensive boilerplate code.Drastically reduces boilerplate.
Setup ComplexityRequires meticulous setup for actions, reducers, etc.Simplifies setup with intuitive API.
Action DefinitionsManual action creation and management.Automatically generates action creators.
Immutable StateRequires careful handling for immutability.Automatically enforces immutability.
Reducer DefinitionsComplex reducer logic often involves switch statements.Simplified slice-based reducers.
Developer ExperienceSteeper learning curve and increased verbosity.Improved developer experience and readability.

Redux Toolkit, with its simplified and intuitive API, reduces the development effort and complexity, making it the preferred choice for many React Native developers. In this guide, we will walk you through the steps of integrating Redux Toolkit with React Native, enhancing your state management workflow.

Setting Up a New React Native Project

Before diving into Redux Toolkit, you need to set up a new React Native project. Here are the steps to get your project up and running:

Prerequisites

To start a Redux Toolkit project in React Native, make sure you have the following prerequisites in place:

  1. Node.js: Ensure that you have Node.js installed on your development machine. You can download it from nodejs.org.
  2. npm or yarn: npm (Node Package Manager) comes bundled with Node.js, while yarn is an alternative package manager. You can choose either of them, but we’ll use npm in this guide.
  3. React Native CLI: Install the React Native command-line interface globally using npm. You can do this by running the following command: npm install -g react-native-cli

Now that you’ve met the prerequisites, let’s create a new React Native project.

Creating a New React Native Project

To initiate a new React Native project, you can use the npx command, which comes with npm (version 5.2.0 and higher). Here’s how to create a new project:

  1. Open your terminal and navigate to the directory where you want to create your project.
  2. Run the following command to create a new React Native project: npx react-native init MyReduxToolkitApp
    Replace MyReduxToolkitApp with your preferred project name. This command will set up a new React Native project with the necessary files and dependencies. It may take a few minutes to complete.
  3. Once the project creation process finishes, navigate into your project directory: cd MyReduxToolkitApp

Now, you have a fresh React Native project ready for integrating the Redux Toolkit.

Installing Redux Toolkit and Dependencies

To harness the power of Redux Toolkit in your React Native project, you need to start by installing Redux Toolkit and its related dependencies. In this section, we will:

What is Redux Toolkit and Why Is It Beneficial?

Redux Toolkit is a package that simplifies the setup and usage of Redux in your application. It comes with built-in utilities that reduce the amount of boilerplate code, streamline development, and enhance the overall developer experience. With Redux Toolkit, you can focus more on building features and less on repetitive Redux configuration.

Installing Redux Toolkit and Related Packages

Let’s dive into the installation process. You can install Redux Toolkit, along with other essential dependencies, using npm or yarn. Here’s how to do it:

Using npm:

Open your terminal and navigate to the root directory of your React Native project.

Run the following command to install the Redux Toolkit: npm install @reduxjs/toolkit

Additionally, you’ll need to install react-redux, which connects Redux to your React Native components: npm install react-redux

Using yarn:

If you prefer yarn, you can use the following command instead: yarn add @reduxjs/toolkit react-redux

Purpose of Each Dependency

Now that you’ve installed Redux Toolkit and react-redux, let’s briefly discuss the purpose of each dependency:

  1. Redux Toolkit (@reduxjs/toolkit): This is the core package that simplifies the process of creating a Redux store, defining reducers, and managing the overall state of your React Native application. It provides utilities like configureStore and createSlice to streamline the Redux setup.
  2. React Redux (react-redux): This package bridges the gap between Redux and React Native components. It offers hooks and a Provider component that allow you to connect your components to the Redux store, access the application state, and dispatch actions seamlessly.

With the Redux Toolkit react-redux in place, you’re now equipped to efficiently manage the state in your React Native application.

Creating a Redux Store with Redux Toolkit

Redux Toolkit excels in simplifying the process of creating a Redux store, reducing the need for verbose setup. In this section, we will explore how Redux Toolkit streamlines this task and guide you through creating a Redux store using the configureStore function.

Simplified Redux Store Setup

Traditionally, setting up a Redux store involved defining reducers, middleware, and enhancers explicitly. Redux Toolkit simplifies this process by offering a unified function, configureStorethat handles all the configuration for you. It comes with sensible defaults while allowing customization when needed.

Creating a Redux Store with configureStore

To create a Redux store using configureStore from the Redux Toolkit, follow these steps:

  1. Open your project’s root file, typically index.js, where you configure your Redux store.
  2. Import the necessary dependencies at the top of your file:
   import { configureStore } from '@reduxjs/toolkit';
   import rootReducer from './reducers'; // Import your root reducer
JSX

Make sure to replace './reducers' it with the actual path to your root reducer.

  1. Use the configureStore function to create your Redux store. Pass in your rootReducer as the reducer option:
   const store = configureStore({
     reducer: rootReducer,
   });
JSX

This single line of code sets up your Redux store with sensible defaults and includes essential middleware like Redux DevTools Extension integration.

Configuration Options with configureStore

While Redux Toolkit provides sensible defaults, you can customize your store’s configuration by passing additional options to configureStore. Here are some commonly used options:

  • middleware: Allows you to specify additional middleware to be applied to the store. For example, you can include Redux Thunk for handling asynchronous actions.
  • devTools: Controls whether Redux DevTools Extension integration is enabled. Set it to true enable DevTools or provide a custom configuration object for more advanced settings.
  • preloadedState: If you need to initialize your store with a predefined state, you can pass it as preloadedState.
  • enhancers: Lets you add custom enhancers to the store. This is less common but provides flexibility when needed.

Here’s an example of how to customize the store creation process with some of these options:

const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(myCustomMiddleware),
  devTools: process.env.NODE_ENV !== 'production', // Enable DevTools in development only
  preloadedState: initialState, // Initialize with a predefined state
});
JSX

With your Redux store now configured, you’re ready to define and manage your application state using the Redux Toolkit.

Defining Slice Reducers with Redux Toolkit

Redux Toolkit introduces the concept of “slices,” which simplifies the process of defining reducers, initial states, and action creators. In this section, we’ll delve into the concept of slices, and demonstrate how to create slice reducers using createSlice, and explain how Redux Toolkit automates the generation of action creators for slice reducers.

Understanding Slices in Redux Toolkit

In traditional Redux, reducers can become complex and verbose, especially in large applications. Redux Toolkit addresses this issue by encouraging the organization of your state into “slices.” A slice is a self-contained portion of your application’s state, including its reducer logic, actions, and initial state. This modular approach enhances code maintainability and readability.

Creating Slice Reducers with createSlice

To create a slice reducer with Redux Toolkit, you’ll typically follow these steps:

  1. Import the necessary dependencies:
import { createSlice } from '@reduxjs/toolkit';
JSX
  1. Define your initial state using createSlice:
   const initialState = {
     // Define your initial state properties here
     // For example:
     items: [],
     loading: false,
   };
JSX
  1. Use the createSlice function to create a new slice:
   const mySlice = createSlice({
     name: 'mySliceName', // Unique name for your slice
     initialState, // The initial state you defined
     reducers: {
       // Define your reducer functions here
       addItem: (state, action) => {
         // Modify state based on the action payload
         state.items.push(action.payload);
       },
       setLoading: (state, action) => {
         state.loading = action.payload;
       },
     },
   });
JSX
  1. createSlice automatically generates action creators for each reducer function you define. For example, in the code above, it generates addItem and setLoading action creators.

Automated Action Creators

One of the significant benefits of using Redux Toolkit is that it automates the generation of action creators. You no longer need to write separate action creator functions manually; they are created for you when you define reducers within a slice.

Here’s how you can dispatch actions using the generated action creators:

import { useDispatch } from 'react-redux';
import { mySlice } from './mySliceFile'; // Import your slice

const dispatch = useDispatch();

// Dispatching the 'addItem' action
dispatch(mySlice.actions.addItem({ name: 'New Item' }));

// Dispatching the 'setLoading' action
dispatch(mySlice.actions.setLoading(true));
JSX

By adopting slices and the createSlice function, the Redux Toolkit simplifies your Redux code, makes it more maintainable, and enhances developer productivity.

Combining Slices and Configuring Middleware

In a typical React Native application, you may have multiple slices of your state, each managed by its respective reducer. Redux Toolkit simplifies the process of combining these slices into a single root reducer and configuring middleware. In this section, we’ll explore how to combine slices and set up middleware like Redux Thunk or Redux Saga.

Combining Multiple Slices

Redux Toolkit provides a convenient utility, combineReducers, to combine multiple slice reducers into a single root reducer. Here’s how you can do it:

  1. Import your slice reducers at the top of your root reducer file:
   import { combineReducers } from 'redux';
   import sliceReducer1 from './slice1';
   import sliceReducer2 from './slice2';
   // Import other slice reducers as needed
JSX
  1. Combine the slice reducers into a root reducer using combineReducers:
   const rootReducer = combineReducers({
     slice1: sliceReducer1,
     slice2: sliceReducer2,
     // Add other slices here
   });

   export default rootReducer;
JSX

With this setup, your Redux store now has a single root reducer that manages the state of all your slices.

Subscribe to Tech Break

Configuring Middleware with Redux Toolkit

Redux Toolkit simplifies configuring middleware by providing the middleware option when creating the store with configureStore. You can easily include middleware like Redux Thunk or Redux Saga for handling asynchronous actions.

Here’s how to configure middleware with Redux Toolkit:

  1. Import the middleware you want to use at the top of your store configuration file:
   import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
   import rootReducer from './reducers';
   import thunkMiddleware from 'redux-thunk'; // Import Redux Thunk
JSX
  1. Use the getDefaultMiddleware function to get the default middleware provided by Redux Toolkit:
   const middleware = [...getDefaultMiddleware()];
JSX

This ensures that you include Redux Toolkit’s default middleware, which is crucial for DevTools integration and other essential features.

  1. Add any additional middleware you want to use to the middleware array:
   middleware.push(thunkMiddleware); // Add Redux Thunk middleware
JSX

You can also include other middleware like Redux Saga if needed.

  1. Pass the middleware array to the middleware option when creating your Redux store:
   const store = configureStore({
     reducer: rootReducer,
     middleware,
   });
JSX

With this setup, your Redux store is configured to use the specified middleware for handling asynchronous actions and other middleware-related tasks.

By combining slices and configuring middleware with Redux Toolkit, you have a streamlined and efficient way to manage your React Native application’s state.

Integrating Redux Toolkit with React Native Components

Now that we’ve set up the Redux Toolkit and configured our store, it’s time to integrate it with React Native components. Redux Toolkit seamlessly connects your components to the Redux store, allowing you to access the application state and dispatch actions efficiently. In this section, we’ll demonstrate how to achieve this integration using the useDispatch and useSelector hooks and showcase the usage of generated action creators for dispatching actions within components.

Connecting React Native Components

To connect your React Native components to the Redux store, follow these steps:

  1. Import Dependencies: At the top of your component file, import the necessary dependencies:
   import React from 'react';
   import { View, Text, Button } from 'react-native';
   import { useDispatch, useSelector } from 'react-redux';
   import { mySlice } from './mySliceFile'; // Import your slice and actions
JSX

Replace './mySliceFile' with the actual path to your Redux Toolkit slice file.

  1. Access State with useSelector: You can use the useSelector hook to access specific parts of your application state. For example, to access a state property named items from your Redux store:
   const items = useSelector((state) => state.mySlice.items);
JSX

Here, mySlice corresponds to the name of your slice.

  1. Dispatch Actions with useDispatch: To dispatch actions, use the useDispatch hook. You can directly dispatch actions generated by Redux Toolkit:
   const dispatch = useDispatch();

   // Dispatching an action using the generated action creator
   const addItemHandler = () => {
     dispatch(mySlice.actions.addItem({ name: 'New Item' }));
   };
JSX

Here, mySlice.actions.addItem is an example of a generated action creator.

Example React Native Component

Let’s put it all together in a simple React Native component:

import React from 'react';
import { View, Text, Button } from 'react-native';
import { useDispatch, useSelector } from 'react-redux';
import { mySlice } from './mySliceFile';

const MyComponent = () => {
  const items = useSelector((state) => state.mySlice.items);
  const dispatch = useDispatch();

  const addItemHandler = () => {
    dispatch(mySlice.actions.addItem({ name: 'New Item' }));
  };

  return (
    <View>
      <Text>Items:</Text>
      <View>
        {items.map((item, index) => (
          <Text key={index}>{item.name}</Text>
        ))}
      </View>
      <Button title="Add Item" onPress={addItemHandler} />
    </View>
  );
};

export default MyComponent;
JSX

In this example, the component connects to the Redux store, accesses the items state, and dispatches an action to add a new item.

With Redux Toolkit, connecting React Native components to the Redux store is straightforward, and generated action creators make dispatching actions more intuitive.

Handling Asynchronous Actions with Redux Toolkit

Asynchronous actions are a common requirement in React Native applications, such as fetching data from APIs. Redux Toolkit simplifies handling such asynchronous actions through the createAsyncThunk utility. In this section, we’ll discuss how Redux Toolkit streamlines asynchronous action handling and provide examples of creating and using async actions with createAsyncThunk.

Simplifying Asynchronous Actions with createAsyncThunk

Traditionally, managing asynchronous actions in Redux involved writing action creators for three different states: request, success, and failure. Redux Toolkit streamlines this process with createAsyncThunk. It automatically generates action creators and reducers for these three states, reducing boilerplate and improving code readability.

Creating an Async Action with createAsyncThunk

To create an async action with createAsyncThunk, follow these steps:

  1. Import Dependencies: At the top of your slice file, import createAsyncThunk and any other dependencies you need:
   import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
   import myApi from '../api/myApi'; // Replace with your API module
JSX
  1. Define the Async Action: Use createAsyncThunk to define your async action. It takes a unique name, an async function that performs the API call, and an optional configuration object:
   export const fetchItems = createAsyncThunk('mySlice/fetchItems', async () => {
     const response = await myApi.getItems(); // Replace with your API call
     return response.data;
   });
JSX

In this example, fetchItems is an async action that fetches items from an API.

  1. Reducers Generated Automatically: Redux Toolkit automatically generates reducers for the request, success, and failure states of the async action. These reducers are accessible through the reducers property of the slice:
   const mySlice = createSlice({
     name: 'mySliceName',
     initialState,
     reducers: {
       // Your other reducers here
     },
     extraReducers: (builder) => {
       builder
         .addCase(fetchItems.pending, (state) => {
           // Handle the pending state (e.g., set loading flag)
         })
         .addCase(fetchItems.fulfilled, (state, action) => {
           // Handle the fulfilled state (e.g., update state with data)
         })
         .addCase(fetchItems.rejected, (state, action) => {
           // Handle the rejected state (e.g., set error flag)
         });
     },
   });
JSX

You can access these reducers through mySliceName.pending, mySliceName.fulfilled, and mySliceName.rejected, where mySliceName is the name of your async action.

Using the Async Action in a Component

To use the async action in a React Native component:

  1. Import the Async Action: Import the fetchItems async action at the top of your component file:
   import { fetchItems } from './mySliceFile'; // Import your slice file
JSX
  1. Dispatch the Async Action: Dispatch the async action in your component using useDispatch:
   const dispatch = useDispatch();

   // Dispatch the async action to fetch items
   useEffect(() => {
     dispatch(fetchItems());
   }, [dispatch]);
JSX

The fetchItems action will automatically trigger the pending, fulfilled, or rejected state based on the API call’s outcome.

Handling asynchronous actions with Redux Toolkit’s createAsyncThunk simplifies your code and improves readability, making it easier to manage API calls and other async operations in your React Native application. In the next section, we’ll explore how to debug your Redux Toolkit-powered app, including integrating Redux DevTools Extension.

Debugging Redux Toolkit with DevTools

Debugging is an essential part of the development process, and Redux Toolkit makes it easier with the integration of Redux DevTools Extension. In this section, we’ll explain how to integrate Redux DevTools Extension with Redux Toolkit for debugging and demonstrate how to use the DevTools to inspect the state and actions in a React Native app.

Integrating Redux DevTools Extension

To integrate Redux DevTools Extension into your Redux Toolkit-powered React Native app, follow these steps:

  1. Install the Redux DevTools Extension: Ensure that you have the Redux DevTools Extension installed in your browser. You can find it for popular browsers like Chrome and Firefox as browser extensions.
  2. Enhance the Store Configuration: In your Redux store configuration file, you can enable Redux DevTools Extension by including it as middleware when creating the store:
   import { configureStore } from '@reduxjs/toolkit';
   import rootReducer from './reducers';

   const store = configureStore({
     reducer: rootReducer,
     middleware: (getDefaultMiddleware) =>
       getDefaultMiddleware({
         serializableCheck: false, // Disable strict serializability checks
       }).concat(/* Add other middleware here */),
   });

   export default store;
JSX

Ensure that you include it as one of the middleware items in the middleware array.

Using Redux DevTools for Debugging

With Redux DevTools Extension integrated, you can access the DevTools panel in your browser while your React Native app is running. Here’s how to use it for debugging:

  1. Open Redux DevTools Extension: Open your browser’s DevTools panel. You should see a “Redux” tab or similar, depending on the extension you installed.
  2. Inspect State: In the DevTools panel, navigate to the “State” tab. Here, you can inspect the current state of your Redux store. You can expand the state tree to view the values of each state property.
  3. Monitor Actions: Switch to the “Actions” tab to monitor dispatched actions. Redux DevTools records every action that occurs in your application. You can click on specific actions to see their details, including the payload.
  4. Time Travel Debugging: Redux DevTools also enables “time travel” debugging. You can navigate through the action history using the buttons provided. This feature allows you to rewind and replay actions, making it easier to track down bugs and understand how your application’s state changes over time.
  5. Dispatch Actions: In the “Dispatch” tab, you can manually dispatch actions for testing purposes. This can be handy for triggering specific actions and observing their effects on the state.

Redux DevTools Extension provides powerful tools for debugging your Redux-powered React Native app, helping you understand state changes, track actions, and identify issues more efficiently. With Redux Toolkit and Redux DevTools Extension combined, you have a robust set of tools to streamline your state management workflow and debug your React Native application effectively.

Conclusion

In this guide, we’ve explored the seamless integration of Redux Toolkit with React Native, simplifying state management in your mobile applications. Redux Toolkit’s intuitive API, automatic action generation, and support for asynchronous actions with createAsyncThunk enhance your development experience.

By following the steps outlined in this tutorial, you’ve learned how to:

  • Set up a Redux Toolkit project in React Native efficiently.
  • Create a Redux store with configureStore and configure middleware.
  • Define slice reducers and utilize generated action creators.
  • Combine multiple slices into a root reducer.
  • Handle asynchronous actions gracefully using createAsyncThunk.
  • Debug your application with Redux DevTools Extension.

With Redux Toolkit’s streamlined approach, you can focus on building feature-rich React Native applications while enjoying improved code maintainability and developer productivity. Incorporate these practices into your projects and elevate your state management game.

As you continue to explore the world of Redux Toolkit and React Native, you’ll discover even more ways to enhance your app development process.

Happy coding!

Share this Content
Snehasish Konger
Snehasish Konger

Snehasish Konger is the founder of Scientyfic World. Besides that, he is doing blogging for the past 4 years and has written 400+ blogs on several platforms. He is also a front-end developer and a sketch artist.

Articles: 192

Newsletter Updates

Join our email-newsletter to get more insights

Leave a Reply

Your email address will not be published. Required fields are marked *