Edupala

Comprehensive Full Stack Development Tutorial: Learn Ionic, Angular, React, React Native, and Node.js with JavaScript

React Native Redux Tutorial with examples

In this tutorial we will learn about the React Native Redux, The Redux is predictable state management not specific to React Native. Redux is a popular state management library for JavaScript. We can use redux in React for creating stores and it is often combined with React and React Native via the React-Redux library.

React Redux is a state management tool, when our application grows, we need a state management tool like Redux to manage the global state, it can access across many parts of our React application.

Object of React Native Redux Tutorial

Redux helps in managing the global state of an application, making it easier to access and update data from different components. It follows a unidirectional data flow pattern, where the state is stored in a central store and can only be modified through actions. We have a few objectives in this article on the React native redux tutorial, here are our objectives

  • How to configure and install redux in the React Native application
  • Demonstrate an example of React Native Rudex state management

Steps for using React Native Redux in the application

Here are the key steps to implement Redux in a React Native app:

  1. Create a React native redux project and configure the project by installing the required packages redux, react-redux, etc.
  2. Create a Redux store using the configureStore from the @reduxjs/toolkit. We need to define a reducer in it.
  3. Define Reducer and action, the reducer to change the state
  4. Setup Provider, wrap your root component with the Provider component from React Redux
  5. Connect redux to the application

React Native Redux Example

Below we have a screenshot of our react native context example, We store the orders selected by the user in the context of the Product Screen component and we used this order to display on the Cart Screen.

Step 1: Install Redux and React redux: We have two screens ProductsScreen and CartScreen, and one component to display the product item. We used redux to store about the selected products id, and add functions to add or remove product id in store ids array object. Let’s create react redux ecommerce app, and install the following packages to our react project.

npm install @reduxjs/toolkit react-redux redux --save

The @reduxjs/toolkit, will make our life easier, With @reduxjs/toolkit, we don’t need to install thunk separately it is included in reduxjs/toolkit and we can perform the async operation with createAsyncThunk function. We also used react navigation for navigation, if you don’t knoz how to conifgure and install react native navigation please check our previous article.

Step 2: Create a React native Redux Store
Create a directory to organize your Redux-related code. Conventionally, you can create a store/redux directory inside your project’s root directory. Inside the redux directory, create a file called store/redux/store.js to set up your Redux store:

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

import ordersReducer from "./orders";

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

To use Redux, you first need to create a store. The store is the central hub for your app’s state. It holds all of the data that your app needs to function, and it provides a way for components to access that data. Redux is based on the unidirectional data flow pattern, which means that data can only flow one way through your app: from the store to the components. This helps to prevent bugs and makes your app easier to reason about.

Step 3: Define Actions and Reducers for React native redux examples
Once you have created a store, you need to create reducers. Reducers are functions that are responsible for updating the state of the store. They take the current state of the store and an action as input, and they return the new state of the store. In traditional redux we used action.type with switch but we dont need it and we can have createSlice function, This function automatically generates action creators and action types for you, allowing you to define reducers and actions in a single, organized object.

Actions are plain JavaScript objects that are used to communicate with the store. They have a type property that indicates the type of action, and they can have any other properties that you need. Let create file store/redux/orders.js

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

const ordersSlice = createSlice({
  name: "orders",
  initialState: {
    ids: [],
  },
  reducers: {
    addOrder: (state, action) => {
      state.ids.push(action.payload.id);
    },
    removeOrder: (state, id) => {
      state.ids.splice(state.ids.indexOf(action.payload.id), 1);
    },
  },
});

export const addOrder = ordersSlice.actions.addOrder;
export const removeOrder = ordersSlice.actions.removeOrder;
export default ordersSlice.reducer;

In reducers, we have two functions, the addOrder call when the user add new product to the cart or orders and removeOrder when the order is removed from the cart.

Step 4: Setup the Provider for React native redux example
Our application has to know about our Redux store, and for that, we are injecting the store using the Provider component on the App component. We need to wrap your root component with the Provider component from React Redux. The Provider component makes the Redux store available to all components in your app.

import { StatusBar } from "expo-status-bar";
import { StyleSheet } from "react-native";
import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import { AntDesign } from "@expo/vector-icons";
import { Provider } from "react-redux";
import CartScreen from "./screens/CartScreen";
import ProductsList from "./screens/ProductsList";
import { store } from "./store/redux/store";

const Stack = createStackNavigator();

export default function App() {
  return (
    <Provider store={store}>
      <NavigationContainer>
        <StatusBar style="light" />
        <Stack.Navigator
          initialRouteName="Product"
          screenOptions={{
            headerStyle: { backgroundColor: "#f4511e" },
            contentStyle: { backgroundColor: "#bdbebd" }, // Different style option
            headerTitleStyle: {
              fontWeight: "bold",
            },
            headerTintColor: "white",
          }}
        >
          <Stack.Screen
            name="Products"
            component={ProductsList}
            options={({ route, navigation }) => {
              return {
                title: "Products",
                headerRight: () => (
                  <AntDesign
                    name="shoppingcart"
                    color="white"
                    size={18}
                    style={{ padding: 10, marginRight: 10 }}
                    onPress={() => navigation.navigate("Cart")}
                  />
                ),
              };
            }}
          />
          <Stack.Screen
            name="Cart"
            component={CartScreen}
            options={{
              title: "Cart",
            }}
          />
        </Stack.Navigator>
      </NavigationContainer>
    </Provider>
  );
}

Step 4: Connect the component to the Redux Store

Components can access the state of the store using selectors. Selectors are functions that take the current state of the store as input and return a specific piece of data. To update the state of the store, you dispatch an action. Dispatching an action tells the store to call the appropriate reducer. The reducer then updates the state of the store and returns the new state.

Before we call the dispatch, we have dummy data and Product components in custom components, let’s create and configure the required components, screens, and dummy data.

In the Products screen, we are listing all the products from dummy data, to display each product we are using the custom Product component in the components folder. In later articles, we will add code to display all products in screens/productList.js components

import { ScrollView } from "react-native";
import Product from "../components/Product";
import { PRODUCTS } from "../data/products";

const ProductsList = () => {
  return (
    <ScrollView>
      {PRODUCTS?.map((item) => (
        <Product
          id={item.id}
          title={item.title}
          imageUrl={item.imageUrl}
          price={item.price}
          description={item.description}
          key={item.id}
        />
      ))}
    </ScrollView>
  );
};

export default ProductsList;

We had consume dummy data and let’s add our dummy data in the data folder to file products.js First we need to define a model for Products in the models/Product.js file as here.

class Product {
    constructor(id, title, imageUrl, price, description) {
      this.id = id;
      this.title = title;
      this.imageUrl = imageUrl;
      this.price = price;
      this.description = description;
    }
  }
  
  export default Product;

Now in the data/products.js file let add dummy data.

import Product from "../models/Product";

export const PRODUCTS = [
  new Product(
    "1",
    "iPhone 9",
    "https://i.dummyjson.com/data/products/1/thumbnail.jpg",
    549,
    "An apple mobile which is nothing like apple"
  ),
  new Product(
    "2",
    "iPhone X",
    "https://i.dummyjson.com/data/products/2/thumbnail.jpg",
    999,
    "SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with"
  ),
  new Product(
    "3",
    "Samsung Universe 9",
    "https://i.dummyjson.com/data/products/4/thumbnail.jpg",
    1200,
    "https://i.dummyjson.com/data/products/3/thumbnail.jpg",
    1300,
    "Samsung's new variant which goes beyond Galaxy to the Universe"
  ),
  new Product(
    "4",
    "OPPOF19",
    "https://i.dummyjson.com/data/products/5/thumbnail.jpg",
    540,
    "OPPO F19 is officially announced on April 2021."
  ),
  new Product(
    "5",
    "MacBook Pro",
    "https://i.dummyjson.com/data/products/6/thumbnail.png",
    1499,
    "MacBook Pro 2021 with mini-LED display may launch between September, November"
  ),
  new Product(
    "6",
    "Samsung Galaxy Book",
    "https://i.dummyjson.com/data/products/7/thumbnail.jpg",
    1550,
    "Samsung Galaxy Book S (2020) Laptop With Intel Lakefield Chip, 8GB of RAM Launched"
  ),
  new Product(
    "8",
    "Microsoft Surface Laptop 4",
    "https://i.dummyjson.com/data/products/8/thumbnail.jpg",
    1499,
    "Style and speed. Stand out on HD video calls backed by Studio Mics. Capture ideas on the vibrant touchscreen."
  ),
];

In your React Native components, we can connect them to the Redux store using useDispatch hooks from react-redux. This allows the components to access the state and dispatch actions. In components/Product.jsx we had a button to add product ID to the store IDs array using


import { StyleSheet, Alert, Text, View, Button, Image } from "react-native";
import { useDispatch, useSelector } from "react-redux";
import { addOrder, removeOrder } from "../store/redux/orders";

const Product = ({ id, title, imageUrl, price, description, type }) => {
  //const orderIds = useSelector((state) => state.productsOrders.ids);

  const dispatch = useDispatch();

  const onAddToCartHandler = () => {
    Alert.alert(`${title} add to cart`);
    dispatch(addOrder({ id: id }));
  };

  const onRemoveToCartHandler = () => {
    Alert.alert(`${title} remove to cart`);
    dispatch(removeOrder({ id: id }));
  };

  return (
    <View style={styles.rootContainer}>
      <Image source={{ uri: imageUrl }} style={styles.image} />
      <Text style={styles.name}>{title}</Text>
      <Text style={styles.price}>$ {price}</Text>
      <Text style={styles.description}>{description}</Text>
      {type === "product" ? (
        <Button title="Add to cart" onPress={onAddToCartHandler} />
      ) : (
        <Button title="Remove to cart" onPress={onRemoveToCartHandler} />
      )}
    </View>
  );
};

export default Product;

const styles = StyleSheet.create({
  rootContainer: {
    backgroundColor: "#E8E8E8",
    borderRadius: 4,
    margin: 10,
    paddingHorizontal: 10,
    paddingVertical: 20,
  },
  name: {
    fontSize: 16,
  },
  description: {
    fontSize: 14,
  },
  price: {
    fontSize: 12,
  },
  image: {
    width: "100%",
    height: 120,
  },
});

After adding the product ids to the ids array object. We can use redux state, in our case we have only one order ids array object and can use it to display a list of order products. Add code for the screens/cartScreen.js

import { StyleSheet, View, Text } from "react-native";
import { useSelector } from "react-redux";
import Product from "../components/Product";
import { PRODUCTS } from "../data/products";

const CartScreen = () => {
  const orderIds = useSelector((state) => state.productsOrders.ids);

  const ordreProducts = PRODUCTS.filter((product) =>
    orderIds.includes(product.id)
  );

  const totalPrice = ordreProducts.reduce((acc, curr) => acc + curr.price, 0);

  return (
    <View>
      <Text style={styles.total}>
        Total products selected : {ordreProducts.length}
      </Text>
      <Text style={styles.price}>Total Price : {totalPrice} € </Text>
      {ordreProducts?.map((item) => (
        <Product
          id={item.id}
          title={item.title}
          imageUrl={item.imageUrl}
          price={item.price}
          description={item.description}
          key={item.id}
          type="order"
        />
      ))}
    </View>
  );
};

export default CartScreen;

const styles = StyleSheet.create({
  total: {
    fontWeight: "bold",
    margin: 4,
  },
  price: {
    fontWeight: "bold",
    marginHorizontal: 4,
  },
});

Conclusion
In this tutorial, we learned how to use redux in React Native with an example. I hope you will get some ideas on what context is and how to use it in redux. It is good to read the official document in the React redux.

Related React Tutorial

  1. Step-by-Step Guide: Welcome Screen with Lottie-React-Native Animation
  2. React Native Navigation Stack: A Step-by-Step tutorial
React Native Redux Tutorial with examples

Leave a Reply

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

Scroll to top